HTTP Header Explainer

A captured exchange has thirty headers in it and four of them matter. The rest are boilerplate a framework added, caching directives nobody set on purpose, and vendor headers with no documentation anywhere. Paste the block and this labels each line: what it is for, whether it travels with the request or the response, and which ones you need to take out before showing anyone.

HTTP Header Explainer — Paste Headers and See What Each One DoesBuildFigure

Request, response, and the ones that go both ways

The first useful thing to know about a header is which direction it travels. Accept is something a client says; Content-Type is something either side says about the body it is sending; Set-Cookie only ever comes back from a server. Mixing them up produces bugs that are hard to see, such as setting Content-Type on a GET with no body, or expecting Cache-Control on a request to control what a server stores.

Every header in the table is labelled with its direction, and where the answer is genuinely both, it says so and explains how the meaning differs on each side. If you paste a whole exchange, both halves appear and the summary tells you it noticed.

Standard, conventional, and invented on the spot

Not everything with a colon in it is defined anywhere. Roughly three tiers exist. Registered headers have a specification you can read. Widely used conventions such as X-Forwarded-For and X-Request-Id behave consistently enough to rely on but are not standards, and their exact semantics vary by implementation. Then there are headers a service invented for itself, where the only documentation is that service documentation, if it exists at all.

Rate limit headers are the clearest example of the middle tier: nearly every API has them, no two agree on the names, and the reset value is a timestamp in one service and a number of seconds in the next. Anything here is described as common behaviour rather than as a rule, and unrecognised names are reported as unrecognised instead of being guessed at.

Assume the block you pasted is a credential

Captured headers are one of the most reliably leaked secrets in software. Authorization holds a token that works for anyone who copies it. Cookie holds a session that is as good as a password. An API key sits under whatever name the service chose, which may look harmless. These blocks get pasted into tickets, chat channels and public questions every day, and the credential stays valid until someone notices.

Anything matching a credential-shaped name is flagged with a redact marker in the table. Take those values out before the block leaves your machine, and if one already has, rotate it rather than hoping. The flagging matches on common names and will miss a token in a header your organisation named something unusual, so read the values as well as the flags.

The five that explain most confusing behaviour

HeaderWhat it explains
VaryWhy a cache served one user a response meant for another. If the response depends on a request header, the cache has to be told
Access-Control-Allow-OriginWhy a request that works in curl fails in a page. curl has no origin and no browser enforcing one
Content-TypeWhy the body will not parse. A JSON body labelled as form data, or missing a charset, breaks the reader rather than the sender
Cache-ControlWhy a change did not appear. Something between you and the server is holding a copy it was told it could keep
AgeConfirmation of the above. A non-zero value means you are looking at a stored response

Where the values come from matters

Some headers are set by the application, some by a framework, some by a reverse proxy or CDN, and some by the browser itself in a way script cannot influence. When a header has an unexpected value, working out which layer produced it narrows the search enormously. A Server header naming software your team does not run points at the edge. A Content-Encoding you did not configure was almost certainly added by a proxy. X-Forwarded-For is set by whatever proxy handled the request, which is precisely why it cannot be trusted unless your own edge overwrites it rather than appending to it.

The browser-controlled set is worth memorising in outline, because it is what makes a translated curl command behave differently: Host, Connection, Content-Length, Accept-Encoding, Cookie, the Sec-Fetch- family and several more are the browser's business. If you are converting a captured request into code, the curl to fetch converter flags those as it goes.

Reading it, and nothing more

Everything here is a lookup against a table built into the page. Nothing is fetched, no request is made against the host in the block, and the text never leaves the tab. That is the only responsible design for a page whose input is, by definition, a live captured exchange. When you are done, the status code reference covers the number on the status line, and the JWT decoder will show you what is inside a bearer token without sending it anywhere either.

Questions people ask

Are the descriptions taken from the specifications?

No, they are short summaries of common behaviour written to be useful when you are looking at a real capture. Several of the headers covered are conventions rather than registered standards, and even for the standard ones the precise requirements have subtleties that a one-line description cannot carry. Use this to orient yourself, and read the relevant specification before you depend on a detail.

Why is my header listed as unrecognised?

Because it is not in the table. That is most often the right answer for a name beginning with X- or with a vendor prefix: those are defined by whoever runs the service and there is no general meaning to report. It can also happen with a recent standard header or a misspelling, so check the spelling first, then the documentation for the service that sent it.

Does it check whether the values are correct?

No. It identifies each header and describes what it is for. It does not validate a date format, parse a Cache-Control directive list, evaluate a Content-Security-Policy or tell you that a max-age is unreasonably long. Those are separate jobs, and a tool that did them badly would be worse than one that does not attempt them.

Can I paste a whole exchange, request and response together?

Yes. Request lines and status lines are detected and reported separately from the headers, and the summary counts how many headers of each direction it found so you can see that both halves are present. The grouping option will sort them into request-side and response-side if that is easier to read than the order they arrived in.

Is anything sent to the host in the headers?

Nothing at all. No request is made from this page, to that host or to anywhere else, and the text is not stored. The whole page is a lookup table and a parser. This is deliberate, because the input to a tool like this is nearly always a real captured request with a working credential in it.

Related