Summary

  • RFC 3966 defined equality beyond raw text: comparison ignored visual separators and case and matched parameters by name, while global/local form, local context and every parameter name remained material.
  • An equal tel URI pair was only a scoped identifier result. It did not establish one person, physical terminal, current assignment, route, consent, human answer or delivered service.

Telephone numbers are unusually human identifiers. People group digits for memory, add punctuation for readability and write the same destination in several presentational forms. Software, by contrast, wants a stable key. RFC 3966, published in December 2004, resolved that tension by defining both a syntax for tel URIs and a comparison relation that was not mere character equality.

The URI named a resource identified by a telephone number. It did not specify how a particular terminal should seize an outside line, choose tone or pulse signalling, add an international access prefix, interpret call-progress tones or send post-dial digits. Those were dialling actions governed by local configuration. Nor did the URI identify one physical device. A number could address a fixed, mobile or nomadic termination point and support voice, data, fax or another service.

That distinction had been sharpened from RFC 2806. RFC 3966 removed carrier selection, dial-context actions, fax and modem URI forms, pause characters and post-dial strings from the tel scheme. The identifier survived; the instructions moved out. RFC 3601 remains the adjacent history for action-bearing phone strings. It is not the equality mechanism here.

Equality required deliberate forgetting

Two global-number URIs—or two local-number URIs—could compare equal even when their visible strings differed. The comparator removed the presentation separators , ., ( and ) from the number digits. It treated comparison as case-insensitive. It matched parameters by name regardless of the order in which they appeared.

This was not permission to normalize everything. One global and one local URI were not equal under the RFC algorithm simply because an operator believed both could reach the same destination. If one URI contained a parameter name absent from the other, the pair was unequal. A local number’s phone-context participated in identity. An extension participated. Mandatory additional parameters participated.

The result was a selective eraser. Presentation punctuation and case could disappear; scope and semantics could not. A system that compared raw strings would create false differences. A system that stripped all parameters would create false sameness.

URI syntax imposed a preferred serialization order: isub or ext first when present, then phone-context, then other parameters in lexical order. That helped surrounding systems that still compared characters. But RFC 3966’s semantic rule matched parameters by name regardless of received order. Canonical output and correct comparison were related controls, not the same control.

RFC 3986 later supplied the generic URI framework, while RFC 3261 used telephone-subscriber syntax inside SIP and exposed contexts where character-sensitive handling mattered. A robust implementation therefore preserves the original string, parses a structured form, records every normalization step and stores a canonical form without pretending that the canonical serialization was the original evidence.

Context made a local number unique without turning into a route

RFC 3966 preferred global form. Some identifiers—private PBX extensions, emergency codes and other local service numbers—could not be represented globally. A local number therefore required phone-context, expressed as a controlled domain name or the leading digits of a valid global number.

The context and local digits together were intended to form a globally unique identifier. Yet the context was not a prefix to concatenate with the local number. 911 with phone-context=+1 did not become +1-911. A domain context did not even have to resolve to a host; it had to remain under the administrative control of the entity managing that numbering context.

This makes equality narrower than routing. Two local URIs can compare equal because their digits and contexts align. That does not prove that two sites share a dial plan, that DNS provides a gateway, that the number remains assigned or that the caller is permitted to use the context. The RFC itself observed that even global numbers might be stale or unreachable from a particular location.

A receiver using the URI only as an identifier could treat the context as opaque. A receiver trying to place a call had to understand the context and be able to operate within it. The same string therefore supported two decisions with different evidence requirements: identify the resource; attempt to reach it.

A matching parameter set could still be unusable

ext identified a station behind a non-ISDN PBX; isub identified an ISDN subaddress. The two could not coexist in one URI. RFC 4715 later refined ISDN subaddress encoding. RFC 4694, RFC 4759 and RFC 4904 added number-portability, ENUM-dip and trunk-group parameter histories.

RFC 3966 also reserved m- for future mandatory parameters. An implementation encountering an unknown mandatory parameter had to refuse to use the URI. Optional parameters could be ignored. This created an important two-stage decision. Two URIs might carry the same unknown m- parameter and align as structured identifiers, yet a receiver that did not understand the parameter still lacked authority to act on either one.

RFC 5341 later created the tel URI parameter registry procedure, and the current IANA tel URI Parameters registry records the coordinated vocabulary. Registration makes a name discoverable. It does not prove that a value is fresh, that a receiver supports it or that the sender was entitled to assert it. Equality, validity, capability and authority must not collapse into one boolean.

One resource did not mean one human or device

The terminology was careful: a tel URI was a name for a resource identified by a number. During call setup, the same URI could be translated into multiple other URIs. Signalling could negotiate service type. A single termination point could have multiple identifiers, and one number need not select one physical instrument or one human being.

RFC 6116 later described ENUM resolution from E.164 numbers to services and URIs. That resolution adds another receipt: which records were returned at which time. It does not retroactively make RFC 3966 equality an assertion about the endpoint that eventually answers.

Security considerations reinforced the separation. A web client was not permitted to place a call from a tel link without explicit user consent. Calls could incur cost, seize a line, reveal caller information or be malicious. Visible link text could even show one number while targeting another. Equality of two parsed targets says nothing about whether either display was honest or whether the user approved the action.

The maintained documentary record—the RFC Editor information page, errata search and IETF Datatracker entry—establishes the specification’s status and reported corrections. It supplies no deployment rate, collision incident or call outcome.

An auditable implementation therefore needs more than a canonical URI column. Preserve original octets and display text; parsed local/global form; digits before and after separator removal; case transformations; the parameter multiset and received order; canonical order; context type and owner; extension or subaddress; mandatory-parameter recognition and parser version; equality rule and result. Then record assignment freshness, dial-plan transformation, signalling target, selected route, consent, endpoint response, human answer, service and cost separately.

RFC 3966 made comparison useful by forgetting only what the identifier contract declared cosmetic. Its deeper lesson is symmetrical: whatever the contract did not observe must not be smuggled into the word “same.”

Sources