Summary
- RFC 3145 let an L2TP peer attach a PPP-specific cause to a Call-Disconnect-Notify message, but required the attribute to remain optional, nonmandatory and informational.
- A cause code, protocol number and direction together identify the scope of a report; they do not independently prove physical root cause, responsibility, user receipt or an accounting outcome.
- The design made cross-organisational diagnosis more portable without transferring authority to the reporting host or letting free text become a security oracle.
The tunnel knew that the call ended, not what PPP had seen
Layer 2 Tunneling Protocol separated two kinds of machinery. The tunnel connected an access concentrator, the LAC, to a network server, the LNS. Inside that arrangement, PPP negotiated link, authentication and network-layer state. The separation was useful: the tunnel did not need to reproduce every internal decision of PPP. It was also an observability fault line.
An L2TP Call-Disconnect-Notify message could close a session and carry L2TP Result and Error Codes. Those values spoke about the tunnel control transaction. They did not necessarily tell the remote operator whether PPP had timed out, rejected every network control protocol, encountered an echo failure or ended through an administrative decision. The missing explanation became most costly when the LAC and LNS belonged to different organisations. One party saw the user-facing edge; the other saw the PPP state that led to termination.
RFC 3145 inserted a compact receipt into that gap. The PPP Disconnect Cause Code attribute-value pair used IETF Vendor ID zero and Attribute Type 46. It was valid only in the disconnect notification. It carried an enumerated cause, a PPP Control Protocol Number, a direction byte and, optionally, descriptive UTF-8 text. A distant peer could now receive more than “the call is gone.”
The extension did not erase the boundary it crossed. It said the new attribute should accompany, not replace, the L2TP Result and Error Code attributes. A PPP cause and a tunnel result were parallel observations. Treating one as a substitute for the other would discard the very layering that made the evidence interpretable.
Mandatory zero was an architectural statement
The new attribute's Mandatory bit had to be zero. That rule was not a typographical detail. An older or simpler peer could ignore a diagnostic it did not understand without being forced to reject the control message. Disconnect processing remained interoperable even when explanation was unevenly deployed.
The same restraint appeared in the document's effect rule. The cause attribute was for information and logging. It should not change the operation of the tunnel or the PPP session. A diagnostic was allowed to describe an act that had already occurred; it was not allowed to become a second control plane merely because it contained a plausible reason.
That choice divided three powers that operational systems often collapse. The power to end a session stayed with the existing protocol state machines. The power to report a local observation went to either L2TP host. The power to conclude why the incident occurred stayed outside the one report, where other records could test it.
The optional Hidden bit supplied a further distinction. A peer could hide the attribute using L2TP's underlying mechanism, and later guidance described protecting L2TP with IPsec. Channel integrity and confidentiality can establish who exchanged protected bytes and make alteration less likely. They cannot establish that the sender's local interpretation was complete or correct. A protected assertion remains an assertion.
A reason needed coordinates
RFC 3145 did not define a bare number. It paired the Disconnect Code with the control protocol and direction. That tuple was necessary because “authentication failed” or “parameters were refused” is meaningless without a point of view.
Direction zero meant a global error. Direction one meant at the peer; direction two meant at the local host. For normal LCP termination, the direction identifies which side sent the Terminate-Request. For compulsory encryption or callback, it distinguishes who required the feature and who refused it. For authentication negotiation, it separates protocols rejected by the peer from protocols requested by the peer but unacceptable locally.
The words local and peer are anchored to the host composing the report. A collector that silently rewrites them into “customer” and “provider” creates a claim the wire did not carry. So does a dashboard that turns direction into fault. Refusing a requested mechanism may be the correct policy decision. Sending the last packet does not prove responsibility for everything that preceded it.
The Control Protocol Number adds a second coordinate. Global causes use zero; link-control failures identify LCP; authentication failures identify the authentication protocol; network-control failures normally name the relevant NCP. Where several NCPs fail, several copies of the attribute may be sent. A single copy should identify the most recent failed NCP. Most recent is a selection rule, not a declaration that earlier failures were unimportant.
This is why a normalized event should retain the original tuple. “Cause 16” alone is weaker than code 16 reported by a particular peer, for a particular authentication protocol, in a particular direction, inside a particular CDN and protected by a known transport context. Every removed coordinate increases the temptation to overread the number.
The list covered states, not courtroom findings
The initial registry ranged from zero through twenty. It included no information available, administrative disconnect, normal LCP termination, negotiation timeout, no recognizable LCP packets, a possible loopback signaled by a Magic Number error, echo timeout, multilink mismatches, refused callback or encryption, authentication failures, absence of usable network control protocols and failure to converge on acceptable addresses.
These labels were valuable because two products could encode the same class of observation. They were limited because an observation class is not a complete causal chain. An echo timeout proves that expected replies were not observed at one point. It does not choose among loss, congestion, a dead peer, a blocked return path or a failed local process. “Authentication failed” records a protocol result; it does not license disclosure of whether the name was valid and only the secret was wrong.
RFC 3145 made that last limit explicit. Future extensions should not give an attacker distinctions that turn diagnosis into a username oracle. More detail is not automatically more truth. Detail can change incentives, expose secrets and let repeated probes discover state that was never meant to cross the boundary.
The optional UTF-8 message creates the same discipline in prose. Portable characters make a description displayable. They do not make it canonical, safe for every audience or guaranteed to have reached a user. The free text belongs beside the structured tuple, with its exact source and privacy handling preserved. It should not overwrite the code, and the code should not certify the prose.
Two owners needed a shared receipt
The most revealing line in the RFC is the reason the gap mattered: the access concentrator and network server might not have the same owner or manager. Within one team, an engineer can sometimes correlate private logs by convention. Across an organisational boundary, convention is weak. Each party needs a stable receipt that says what the other side observed without pretending the parties share one state machine or one incentive.
The RFC expected the extension to be especially useful from an LNS to a LAC in compulsory tunneling, while allowing either side to send it. That asymmetry describes likely knowledge, not permanent authority. The LNS might know why its PPP negotiation ended; the LAC might know what happened at the access link. A complete investigation may need both.
The draft history left another useful seam. An earlier form used 3Com Vendor ID 43. RFC 3145 allowed receivers to accept that form as equivalent but told implementations not to transmit it. Compatibility preserved old evidence while the IETF assignment became the forward wire contract. The registry established how to read a field; it did not prove who had deployed it or whether any individual report was accurate.
Accounting required another receipt
The abstract said the cause could help accounting and debugging. The cautious verb matters. RADIUS tunnel-accounting attributes can identify a tunnel, record accounting input and correlate a session. Those records answer questions that a disconnect cause does not: which accounting session was started, when an interim update arrived, whether a stop record was received and how a system applied it.
A cause code can explain why a stop may have occurred. It cannot prove that the stop record settled, that usage counters were complete or that an invoice was correct. Conversely, a clean accounting stop does not prove that the PPP diagnosis was right. The two records should meet through stable identifiers and timestamps, not through one field being declared superior.
The same applies to the data plane. A code for echo timeout should be compared with packet counters, reachability checks and link alarms. An authentication cause should be compared with state transitions while keeping credentials and sensitive text out of broad logs. A normal termination should be compared with the actual LCP exchange. The cause is the index into an investigation, not the investigation's last page.
Running code supplied the appeal
RFC 3145 is a small example of a durable Internet pattern: standardise the minimum message needed for interoperability, then let evidence from operation constrain what institutions may claim about it. The numeric assignment is symbolic authority. The protected CDN is a recorded act. PPP state and packets are operational reality. Accounting and user experience are consequences. None can impersonate the others.
That hierarchy also protects useful diagnostics from becoming political. If a receiving organisation must either accept a peer's code as final truth or discard it as untrusted, cooperation becomes brittle. A better rule is narrower: preserve the claim exactly, preserve who made it, test it against independent receipts and leave uncertainty visible. The report remains valuable because it is bounded.
Twenty-five years later, observability systems still fail at this seam. They ingest a reason supplied by one component, remove the reporter and direction, translate it into a friendly sentence, and promote it to a global incident label. RFC 3145 had already shown the safer construction. A code can cross the tunnel. Authority over reality does not travel with it.
Sources
- RFC 3145 text
- RFC 3145 record
- RFC 3145 HTML
- RFC 3145 document history
- RFC 2661 — Layer Two Tunneling Protocol
- RFC 1661 — The Point-to-Point Protocol
- RFC 2119 — Requirement words
- RFC 2279 — UTF-8
- IANA L2TP parameters
- RFC 3193 — Securing L2TP using IPsec
- RFC 3931 — L2TP version 3
- RFC 2867 — RADIUS tunnel accounting
- Running-Code Primacy
- On Reality Layers
- Minimum Initial Specification
Member Briefing
Deeper Profile Context
Sign in with the right membership level to unlock the full briefing and source notes.
Only for Strategic Circle
Strategic Circle
Open to all readers. Unlock profile briefings after joining and signing in.
Join Strategic CircleOnly for Leadership Alliance
Leadership Alliance
For qualified IP-asset owners and management; sign in to unlock alliance briefings.
Join Leadership Alliance
