Summary

  • HTTPbis posted revision 01 of draft-ietf-httpbis-pre-denied on 9 September 2026. It is an active working-group draft, not an RFC or an approved status-code assignment.
  • The revision renames the response Purpose Declined, proposes code 419, and broadens it to a refusal based on a request’s declared Sec-Purpose. The only token currently defined by Fetch is prefetch.
  • The draft allows an origin or a gateway acting on that origin’s behalf to generate the response. An independent proxy should not. That distinction is an authority boundary, not merely an implementation preference.
  • The response identifies a refusal class, not the deciding policy. I propose a compact purpose-decision record linking the token, actor, delegation, policy version, cache treatment, time and outcome. This is Daniel Kade’s editorial proposal, not draft text.

Revision 01 turns a response into an authority question

The visible change is easy to summarize. At 08:56 UTC on 9 September, the Datatracker made revision 01 of The Purpose Declined HTTP Status Code available. The HTTPbis working-group document now proposes 419 rather than a generic 4xx placeholder. It replaces the narrower phrase “Preliminary Request Denied” and its prefetch-or-preload framing with a response for any request refused because of its declared purpose.

The procedural state is just as important as the number. The document is active, belongs to HTTPbis, sits in the IETF stream and is intended for the Proposed Standard track. Tommy Pauly is listed as document shepherd. Yet the IESG state remains I-D Exists; there is no responsible Area Director, IESG processing state or telechat. The IANA registry still lists 419-420 as unassigned. Revision 01 is therefore current working-group design, not a registered response code.

The decisive addition is about who may speak. The draft says origin servers may generate the response. Gateways such as content-delivery networks or reverse proxies may also do so when acting on an origin’s behalf. Independent proxies should not generate it. Those three sentences determine whether 419 reports the policy of the application authority or merely the preference of an intermediary that happened to see the traffic.

That is governance expressed as protocol placement. A gateway is not authorised by its network position alone. Its authority comes from a relationship with the origin. A transit proxy may possess the technical ability to return any 4xx response, but the draft withholds the semantic right to present its own refusal as the origin’s purpose decision.

The header declares a purpose; it does not prove an intention

The Fetch Standard gives Sec-Purpose a deliberately limited job. It indicates that a request serves a purpose other than immediate use. It is a structured header whose only defined value at this cutoff is prefetch. A server can use that declaration to vary cache lifetime, reject the prefetch or count the visit differently.

Revision 01 adopts the broader name “Purpose Declined” so the response need not be trapped inside today’s sole token. That is sensible extensibility, but it does not manufacture future tokens or new server powers. The draft says it adds no capability: a server can already refuse a request. The proposed response only makes the reason class more legible to clients and operators.

Legibility must not become overclaim. Sec-Purpose: prefetch records what the client declared about this request. It does not prove the user’s subjective intention, establish consent for background loading, identify the software component that initiated the fetch or show that the declaration was honest. Nor does the 419 response reveal the private rule that evaluated the declaration. One origin might reject every prefetch; another might reject it only under load; a gateway might apply a customer policy by geography, cost, abuse signal or content class.

The protocol pair therefore carries two bounded statements: the requester declared a purpose, and an authorised server-side actor declined on that basis. It should not be promoted into a general verdict about the request’s legitimacy.

Delegated gateways need an inspectable mandate

The phrase “acting on their behalf” does substantial work. A CDN can terminate a connection, execute edge logic and generate a response before the origin application sees the request. A reverse proxy may enforce policy close to the application. Those placements can reduce waste, latency and origin load. They also create the possibility that the component producing 419 and the organisation accountable for the policy are different.

An operator debugging the refusal needs more than the status line. Was the decision made by the origin application, a gateway executing an explicit rule, or an intermediary outside the origin’s administrative control? Which tenant or service delegated the rule? Which version was active? Did the gateway evaluate an exception that the origin would have applied? A response code cannot answer those questions without becoming an overloaded policy language.

The correct response is not to embed private rules in public wire text. It is to keep a matching operator record. For each material purpose decline, the record could bind the exact Sec-Purpose token to the deciding component, its role, the origin or tenant on whose behalf it acted, a stable policy identifier and version, the decision time, the outcome and the cache treatment sent. A safe reason class can be included when disclosure will not expose sensitive state.

This is narrower than a universal access log. It records only the claims needed to audit authority and reproduce a disputed decision. It also avoids turning deployment topology into evidence: the fact that a proxy sits close to an origin does not prove that the origin delegated this policy.

Caching is part of the decision boundary

Revision 01 says the response should contain zero-length content and any received content should be discarded. It also says 419 is not heuristically cacheable and should not be cached. This is not editorial tidiness. It limits how far one local decision can travel.

RFC 9110 already says an unknown 419 is interpreted as the x00 member of its class: a client that does not recognise the code still understands a generic 4xx failure. RFC 9111 supplies the general conditions under which responses can be stored. The draft’s stronger no-cache direction prevents a purpose refusal evaluated for one moment, path or policy context from being replayed as if it were a durable answer.

That matters when a gateway is the decision point. A cached refusal can outlive the policy version, survive a load spike, cross a tenant boundary or reach a request with a different purpose context. The status code would then appear to speak for an origin that never made the later decision. Recording cache treatment alongside actor and policy version makes this failure observable.

The draft also acknowledges that a purpose-specific refusal may reveal internal server state. A detailed public explanation can worsen that leak. The division of labour should be clear: the wire response supplies minimal common semantics; the private decision record supplies controlled accountability; operational disclosure policy determines what can safely be shown to a requester.

Sources