Parse modern HTTP fields with Structured Fields

Use a field's declared Structured Field type and the standard algorithms instead of splitting modern HTTP field values by hand.

  • standards updates
  • structured fields
  • fields
  • parsing
  • extensibility

The field definition chooses the parser

Structured Fields provide shared data types and exact parsing and serialization algorithms for HTTP fields. They reduce the need for every new field to invent a slightly different grammar.

They do not redefine every existing HTTP field. Before parsing a value, find the field’s specification or its entry in the IANA HTTP Field Name Registry. A field defined as a Structured Field declares one top-level type:

  • List for an ordered sequence of members.
  • Dictionary for keyed members.
  • Item for one value with optional parameters.

For example, Priority is registered as a Dictionary:

Priority: u=0, i

Expected result: a Structured Fields parser returns a dictionary containing the integer member u with value 0 and the Boolean member i with value true. The syntax does not mean the raw strings "u=0" and "i".

Do not apply the Structured Fields algorithms to an older field merely because its value contains commas, semicolons, or equals signs. Fields such as Cache-Control, Set-Cookie, and Accept have their own definitions.

Separate containers from item types

Lists and Dictionaries can contain Items or Inner Lists. An Item contains one bare value and can carry Parameters. RFC 9651 defines these bare item types:

Type Purpose
Integer Whole numbers within the defined range
Decimal Fixed-precision decimal numbers
String A restricted ASCII string
Token An identifier with a wider unquoted character set
Byte Sequence Binary data represented with base64
Boolean True or false
Date A timestamp represented as seconds since Unix epoch
Display String Unicode text intended for human-facing display

The wire syntax communicates the type. 2, "2", and ?1 are an Integer, a String, and a Boolean; they are not interchangeable values that a recipient should coerce.

Display Strings are not automatically safe to place in HTML, logs, terminals, or another user interface. They can represent control characters and other code points that an application might not accept. A recipient still needs to validate, filter, and escape the parsed value for its output context, and a field definition should constrain which code points are meaningful.

An Inner List preserves a grouped, ordered sequence inside a List or Dictionary. This matters for fields such as Signature-Input, where the order of covered message components is part of the signature metadata.

Treat parameters as structured data

Parameters attach metadata to an Item or Inner List. A parameter without an explicit value has the Boolean value true.

Example-Policy: mode=fast, retries=2, secure

Expected result: if a specification defined Example-Policy as a Dictionary, the parser would produce a Token value for mode, an Integer for retries, and a true Boolean for secure. This invented field demonstrates syntax only; it creates no HTTP semantics.

Parameters and Dictionary members are different levels of the data model. A value such as item;level=2 is one Item with a parameter; it is not equivalent to two Dictionary members.

Use the standard algorithms, not delimiter splitting

A parser built from split(","), split(";"), or split("=") will eventually misread quoted values, byte sequences, Inner Lists, parameters, or valid whitespace. It can also accept invalid forms differently from another implementation.

Use an implementation of RFC 9651 that exposes the declared top-level type. Keep the received value as bytes until the algorithm calls for conversion, preserve ordering where the data model requires it, and serialize through the standard algorithm when a stable wire representation matters.

The ABNF in RFC 9651 is informative. It illustrates the syntax, but the step-by-step algorithms are authoritative because ABNF does not capture every range, processing, and failure rule.

Strict failure is intentional

Structured Fields choose a strict failure model. If parsing fails, a recipient either ignores the complete field value or treats the complete HTTP message as malformed. A field definition is not allowed to relax this into accepting the valid-looking fragments and discarding the rest.

That rule avoids two components assigning different meanings to the same value. It is particularly important when a field affects caching, prioritization, integrity, or signatures.

Forwarding and parsing are separate decisions. An intermediary that does not parse a Structured Field is not automatically required to remove a malformed instance before forwarding it.

Preserve extension points

Structured Dictionaries and parameters are designed to grow. Unless a field’s own specification says otherwise, recipients should ignore unknown members and parameters while continuing to process the recognized ones.

Do not reject a whole valid value only because it contains an unfamiliar extension. Conversely, do not assign meaning to an unknown key from its spelling. The specification that registers or defines the extension supplies its semantics.

When storing or forwarding a parsed value, preserve the distinctions that the field depends on:

  • Item type, rather than only its displayed value.
  • Member and Inner List order where it is significant.
  • Parameters attached to the correct member.
  • Binary data as bytes, not an accidentally recoded string.

Understand the 2024 revision

RFC 9651 was published in September 2024 and obsoletes RFC 8941. The revision adds Date and Display String types, refines parse-failure handling, makes the ABNF explicitly informative, and adds Structured Type information to the IANA field registry.

The new types do not silently extend every field defined under RFC 8941. A field definition still decides which types it accepts. An older implementation can also fail when it encounters a type introduced by RFC 9651, so deployers should test the complete client, proxy, and server path before using a new type.

The RFC Editor currently lists reported erratum 8869. It notes that one explanatory list in section 3.3 omits Display String, while section 3.3.8 and the parsing and serialization algorithms define that type. The erratum is reported, not yet verified, and does not remove Display String from RFC 9651.

Implementation checklist

Before consuming a modern HTTP field:

  1. Confirm that its definition declares Structured Fields.
  2. Obtain the exact top-level type and any field-specific restrictions.
  3. Parse and serialize with the RFC 9651 algorithms.
  4. Fail the whole field value when structured parsing fails.
  5. Ignore valid unknown extensions unless the field definition says otherwise.
  6. Enforce local size and resource limits without changing successful values.
  7. Test repeated field lines and intermediary transformations on the real path.

Structured Fields solve syntax and interoperability. They do not supply the meaning, trust model, or security policy of the field that uses them.

Primary sources