IPv6 zones in URLs are a mistake

IPv6 link-local addresses and their “zone identifiers” (e.g. `fe80::1%eth0`) turn out to be extremely awkward to represent in URLs, colliding with existing URL syntax for percent-encoding and forcing ugly constructs like `http://[fe80::1%25eth0]/`. Commenters describe a tangle of conflicting or obsolete RFCs, inconsistent behavior across languages and browsers, security pitfalls, and broken tooling that either rejects these URLs or parses them differently. Many argue that while zones solve real routing problems for link-local IPv6, they are a poor fit for URIs and that practical setups should rely on ULAs, DNS, or mDNS instead of exposing zone-scoped literals in application URLs.

Standards and RFC confusion

  • Earlier RFCs did not define IPv6 zone identifiers in URIs; RFC 6874 later required percent-encoding % in zone IDs, but was then obsoleted by RFC 9844, which removed URI guidance.
  • This leaves URI syntax effectively back to RFC 3986, which “does not support IPv6 scoped addressing zone identifiers.”
  • Participants see this as a standards mess: existing deployed behavior vs current specs vs browser constraints.

Go, Rust, and library behavior

  • Go’s net/url follows RFC 6874 (e.g., fe80::4%25eth0), which now lacks a live standard but is already widely used.
  • Options discussed: keep current behavior, drop zone support entirely, or support both encoded and unencoded %; the last two are seen as breaking or ugly.
  • Rust libraries are inconsistent: one URL type rejects zones, another accepts both % and %25.
  • Some developers choose to reject IPv6 zone IDs in URLs entirely to avoid ambiguity.

Browsers and practical usability

  • Major browsers dropped support for link‑local URLs with zones after WHATWG decided not to support them.
  • Result: users often cannot access router or device UIs over link‑local IPv6 directly; workarounds involve proxies or tricks like special “ipv6-literal” hostnames.
  • Some suggest browsers should treat the zone purely as a local UI hint and never send it on the wire.

IPv6 syntax and ergonomics

  • Many complain about colons and required brackets in IPv6 literals, especially interacting with tools that also use : (e.g., rsync host:path) and shell globbing with [].
  • Some argue the need for brackets and percent-encoding shows the scheme is “broken”; others reply that clashes with legacy tool syntax are not IPv6’s fault.

Link‑local addresses, zones, and alternatives

  • Link‑local (fe80::/10) is heavily used in IPv6 (e.g., NDP) and can also be used for services via mDNS; this is contrasted with IPv4 link‑local (169.254/16), which is mostly seen as a failure mode.
  • Zones are defended as necessary to disambiguate identical link‑local addresses on multiple interfaces; critics call them an abstraction leak and a high complexity cost.
  • Some recommend using ULAs (fc00::/7) or GUAs for services and avoiding link‑local in applications; others stress legitimate use cases where link‑local + zones are valuable.

Security and validation issues

  • Zone IDs can legally contain characters like ; and $, enabling shell injection if an “IP validator” is naively combined with shell=True or copy‑pasted into a shell.
  • This is used as an example of how IPv6’s permissive zone syntax plus poor tooling assumptions can produce subtle vulnerabilities.

Alternative designs and “what could have been”

  • Suggestions include: different address delimiters, different port separator, using dots or decimal, reserving a TLD or special domain, or treating bracketed hosts as opaque strings passed to getaddrinfo.
  • Some argue zones themselves were a mistake; others see them as essential, with the real mistake being half‑hearted URI and browser support.

Overall sentiment

  • Broad agreement that the interaction of IPv6 zones with URLs and tooling is complex and fragile.
  • Split between “embrace zones, fix the tooling/standards” and “avoid zones/link‑local in application‑level URLs wherever possible.”