IPv6 zones in URLs are a mistake

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.”