What counts as an HTTP message here
An HTTP/1.x message is a start line, a block of Name: value header fields, an empty line and an optional body. The start line is either a request line (GET /api/orders?page=2 HTTP/1.1) or a status line (HTTP/1.1 404 Not Found). The parser accepts all three shapes people actually paste: a full request or response, a response with its body, or just the header lines without any start line, which is what most dev tools copy.
HTTP/2 and HTTP/3 send the same headers in binary frames, but tools such as curl -i print them in this text form with a HTTP/2 200 status line, so those pastes work too.
Using the parser
Paste into the input pane; formatting runs as you type, and Ctrl/Cmd+Enter re-runs it on demand. The built-in HTTP message parser rewrites the message in a consistent shape:
- Header names get their canonical casing:
content-typebecomesContent-Typeandx-request-idbecomesX-Request-ID. Unknown custom headers are left as written. When the status line says HTTP/2 or later, names are lower-cased instead, because that is how they travel on the wire. - Obsolete folded header values (continuation lines starting with a space) are joined into one line, with a warning.
- A body after the blank line is pretty-printed when its
Content-Typeor content is JSON, XML or HTML, andapplication/x-www-form-urlencodedbodies are listed field by field. Compressed bodies (aContent-Encodingsuch as gzip) are left untouched.
The info panel explains what the headers mean together. The Status row gives the reason phrase and what the code means, for example that a 301 means links should be updated to the Location. Caching turns Cache-Control into a sentence such as “Fresh for 1 year; never changes while fresh”. Every Set-Cookie gets a row listing its flags: HttpOnly, Secure, SameSite, Path, and whether it is a session cookie, expires later or deletes the cookie. The Table view lists each header with its value and a one-line meaning. There are no format-specific options.
Problems it catches
Several mistakes in raw messages cause real outages, and the parser reports them as warnings with the line number:
- A
Content-Lengththat does not match the body. The check allows for CRLF line endings and a trailing newline, so it only fires on a genuine mismatch. - Both
Content-LengthandTransfer-Encodingpresent, a classic request-smuggling ingredient. - Repeated headers that must appear once, such as
Content-TypeorHost, especially with conflicting values. - An HTTP/1.1 request without a
Hostheader. - Lower-case methods (
getis notGET; methods are case-sensitive), a missing HTTP version on the request line, malformed status codes and header names containing spaces.
A body declared as JSON that does not parse is shown as written, with a warning instead of an error, so you can still read it.
A note on what you paste
Raw headers routinely contain Authorization bearer tokens, session cookies and API keys. Parsing happens in your browser and the message is not uploaded, but redact credentials before pasting the formatted result into a ticket or chat. If a header carries a JWT, the JWT decoder will show its claims and expiry.
Examples
Redirect response with long-lived caching
Names are re-cased, the cache rule is summarised as one year and immutable, and the cookie is recognised as a deletion.
HTTP/1.1 301 Moved Permanently
location: https://www.example.com/new-path
cache-control: max-age=31536000, immutable
set-cookie: tracking=off; Max-Age=0; Path=/
vary: accept-encoding
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/new-path
Cache-Control: max-age=31536000, immutable
Set-Cookie: tracking=off; Max-Age=0; Path=/
Vary: accept-encoding
JSON POST request with its body
The body after the empty line is pretty-printed as JSON, and its 57 bytes match the declared Content-Length.
POST /api/orders HTTP/1.1
host: api.example.com
content-type: application/json
accept: application/json
content-length: 57
{"sku":"KB-104","qty":1,"shipping":"express","gift":true}POST /api/orders HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Content-Length: 57
{
"sku": "KB-104",
"qty": 1,
"shipping": "express",
"gift": true
}
HTTP/2 response copied from curl -i
Because the status line says HTTP/2, header names are written in lower case as HTTP/2 requires.
HTTP/2 200
Content-Type: text/html; charset=utf-8
Cache-Control: private, no-cache
Strict-Transport-Security: max-age=63072000
HTTP/2 200
content-type: text/html; charset=utf-8
cache-control: private, no-cache
strict-transport-security: max-age=63072000
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
This does not look like a request line ("METHOD /path HTTP/1.1") or a header ("Name: value") | The first line is neither a start line nor a header, often a log prefix or a timestamp copied along with the message. | Delete everything before the request line or the first header. |
Expected a header line "Name: value" | A line without a colon appears among the headers, usually because the empty line before the body is missing. | Insert a blank line between the last header and the body. |
The request line is missing the HTTP version | The request line has a method and path but no protocol, as in GET /api/orders. | Add the version at the end, for example GET /api/orders HTTP/1.1. |
Content-Length says 52 bytes but the body is 57 bytes | The declared length was not updated after the body was edited. A server would cut the body short or wait for missing bytes. | Let your HTTP client compute Content-Length, or set it to the UTF-8 byte length of the body, not the character count. |
Methods are case-sensitive: "get" should be "GET" | HTTP methods are case-sensitive tokens, and most servers reject lower-case ones with 400 or 405. | Write the method in upper case. |
Frequently asked questions
How do I copy raw HTTP headers from Chrome or Firefox?
In the Network panel, select the request and use the Raw toggle in the Headers tab, or right-click the request and choose Copy as cURL. Running that command with curl -i prints a response this parser reads directly.
Are HTTP header names case-sensitive?
No, servers must treat them case-insensitively. The parser still normalises them to the usual capitalisation for HTTP/1.x so messages are easier to compare.
What does Cache-Control: no-cache actually mean?
The response may be stored, but it must be revalidated with the server before every use. To forbid storing it at all, use no-store; the Caching row spells out the difference for each directive.
Can it read an HTTP/2 response?
Yes, in the text form tools like curl print. The status line HTTP/2 200 is accepted and header names are kept in lower case.