Bjorn brought up the point that there are some niche cases where applications do not strictly follow the HTTP message syntax for responses. Specifically, for Shoutcast(?) / Icecast mp3 servers the status-line in the response looks something like this: ICY 200 OK\r\n I have thought about ways to support this directly in Beast but I have decided against it. "ICY 200" is not HTTP according to the RFC, and trying to accommodate this use case places needless technical debt in public interfaces. However, I came up with a very simple technique to make this work with Beast by writing just a tiny bit of extra code. The solution is to implement a stream wrapper which meets the requirements of SyncReadStream[1] and/or AsyncReadStream[2] and forwards the calls to read to the "next layer" object, which will be the actual socket or ssl::stream. The implementation of the icy_stream wrapper can check to see if the first 3 bytes received from the next layer match "ICY" and if so, return a buffer to the caller which replaces those characters with "HTTP/1.1" (or "HTTP/1.0"). With this wrapper, calls to beast::http::read or beast::http::async_read can parse the custom response as a regular HTTP message. The wrapper can embed state information to inform the caller if the "ICY" string was not received. The declaration for such a wrapper might look like this: template<class NextLayer> class icy_stream; Usage for the wrapper: asio::ip::tcp::socket sock{ios}; icy_streamasio::ip::tcp::socket& stream{sock}; beast::http::responsebeast::http::empty_body res; beast::multi_buffer buffer; beast::http::read(stream, buffer, res); This technique may of course be generalized to support any desired similar but non-standard HTTP requests or responses in a fashion that is completely transparent to Beast. Thanks [1] http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/SyncReadS... [2] http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/AsyncRead...