skip to content

Why did RFC 6929 add Extended-Type-1 (241) and Long-Extended-Type-1 (245) to RADIUS attribute encoding?

level: seniorimportance: should knowfreq 30%

answer

  1. one octet of type space ran out
  2. spend a type to get a namespace
  3. each header octet costs a value octet
  4. the More bit chains fragments
  5. 241 opens space, 245 also fragments

basics

~20 s

The one-octet Type field ran out of numbers. RFC 6929 spends a type on a second level: Extended-Type-1 (241) adds an Extended-Type octet opening a fresh value space, and Long-Extended-Type-1 (245) adds a Flags octet whose More bit lets one value span several attributes.

solid answer

~40 s

The `Type` field is one octet, so the standard space holds a few hundred values and it filled up. RFC 6929 spends one of the remaining numbers on a second level of indirection: an `Extended-Type-1` (241) attribute is `Type` 241, `Length`, then an **`Extended-Type`** octet selecting within a fresh 256-value space, leaving at most 252 octets of value. `Long-Extended-Type-1` (245) adds one more octet, a **`Flags`** field whose most significant bit — `M`, for *More* — says the value continues in the next attribute of the same extended type, so a long value can be carried in fragments and reassembled in order. That extra octet costs payload, leaving 251 per fragment. Nothing else changed: `Length` is still one octet and the packet is still capped at 4096.

code

pseudocode · 16 lines
pseudocode
standard attribute:
  Type | Length | Value                                # value <= 253

Extended-Type-1 (241):
  Type=241 | Length | Extended-Type | Value           # value <= 252

Long-Extended-Type-1 (245):
  Type=245 | Length | Extended-Type | Flags | Value   # value <= 251
     Flags: most significant bit M = more fragments follow

reassembling a long value:
  parts = empty
  for each attribute of this extended type, in order:
      append its Value to parts
      if M bit is clear:
          stop                                        # last fragment

go deeper

for a junior

Recall the shape of the problem: attribute numbers are one octet wide and ran out, so a later specification used one of the remaining numbers to open a second, larger space behind it.

for a middle

Explain both additions precisely — an Extended-Type octet for namespace, a Flags octet with a More bit for fragmentation — and why each extra header octet reduces the value a fragment can carry.

for a senior

Show the deployment reality: an older receiver ignores an unknown type silently, so an extended attribute can be sent for months with no effect and no error, and you need a way to detect that before relying on it.

for a principal

The bet to weigh is committing an estate's vocabulary to an encoding only newer equipment understands, when field devices turn over slowly and the failure mode is silence rather than a fault anyone reports.

## A namespace that filled up RADIUS identifies an attribute by a single octet. That was ample when the protocol was written and it is not ample now: standard attributes, accounting attributes, tunnel attributes, IPv6 attributes and everything else added over decades all draw on the same few hundred numbers, and the space ran short. The obvious fix — widen the `Type` field — is impossible, because every deployed implementation walks the attribute list by reading one octet of type and one of length. Changing the header changes the walk for every attribute, and there is no flag day on which the world's access equipment would do it together. RFC 6929 takes the only route that preserves the walk: **spend a type number to buy a namespace**. ## Extended-Type-1 (241) An attribute of `Type` 241 keeps the familiar header and then adds one octet before the value: 1. `Type` = 241 — an ordinary type number as far as the list walk is concerned. 2. `Length` — still one octet, still counting the whole attribute. 3. **`Extended-Type`** — one octet selecting an attribute *within* the 241 space. 4. `Value` — the rest. An old receiver walking the list sees a well-formed attribute with a type number it does not know, and does what it always does with an unknown type: it ignores it and steps on. A receiver that implements RFC 6929 reads the extra octet and knows which extended attribute this is. The cost is one octet of payload: 253 minus the `Extended-Type` octet leaves **252 octets of value**. ## Long-Extended-Type-1 (245) The second problem RFC 6929 addresses is the 253-octet ceiling itself, which the base format offers no generic way past. `Long-Extended-Type-1` (245) has the same shape as 241 plus one more octet: 5. **`Flags`** — one octet whose most significant bit is `M`, for *More*. When `M` is set, the value continues in the next attribute of the same extended type; when it is clear, this is the last fragment. A receiver reassembles a long value by concatenating the fragments in the order they appear. That is the first genuinely *generic* fragmentation in RADIUS: it belongs to the format rather than to one attribute's private definition, so any attribute defined in the long extended space gets it without inventing its own rule. The second extra octet costs another octet of payload, leaving **251 octets per fragment**. | Format | Header octets before the value | Maximum value | |---|---|---| | Standard attribute | `Type`, `Length` | 253 octets | | `Extended-Type-1` (241) | plus `Extended-Type` | 252 octets | | `Long-Extended-Type-1` (245) | plus `Extended-Type` and `Flags` | 251 octets per fragment | ## What did not change It is as important to know the limits this did not lift: - **`Length` is still one octet.** No individual attribute got bigger; the long format spreads a value across several attributes rather than enlarging one. - **The packet is still capped at 4096 octets.** Fragmentation lets a value exceed 253 octets, not the packet. - **Old receivers do not understand it.** They ignore the unknown type, which is graceful but silent — the attribute simply has no effect, and nothing reports that it did not. - **Standard attributes are untouched.** Everything already defined below the extended range keeps its number and its encoding. ## Reading it as a pattern The extended types are the third time this protocol has solved a problem by putting a new field inside a value rather than in the header — after the vendor namespace under `Vendor-Specific` (26) and the group tag inside tunnel attribute values. Each one buys capability at the price of an out-of-band decoding rule both ends must already know. When an estate's equipment spans many generations, the question to ask of any of them is not whether the format supports what you need, but whether the equipment in the field will understand the octets you are about to send — and, since the failure mode is silence rather than an error, how you would find out that it did not.

  • What does a receiver that predates RFC 6929 do with an Extended-Type-1 (241) attribute?
    It treats it as an ordinary attribute with an unknown `Type` and ignores it, stepping over it using `Length` exactly as it would any other. That is the point of spending a type number instead of widening the header: the list walk still works, so nothing breaks — but the attribute has no effect and no error says so.
  • Why does Long-Extended-Type-1 (245) carry one octet less of value than Extended-Type-1 (241)?
    Because it adds the `Flags` octet on top of the `Extended-Type` octet. Both come out of the same 253-octet budget a one-octet `Length` allows, so 241 leaves 252 octets and 245 leaves 251 per fragment. Every field placed in front of the value is paid for out of the value.

saying these in an interview costs you the question

  • Thinks the extended formats widened the Length field.
  • Says Extended-Type-1 (241) can also fragment a long value.
  • Believes the M bit is set on the final fragment.
  • Assumes an implementation predating RFC 6929 parses type 241 correctly.
  • Claims the extended formats lifted the 4096-octet packet cap.