Files
hq/04-ISSUES/191-a-route-with-only-an-internal-name-is-dropped/00-report.md
T

2.7 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
located 2026-10-01
mesh-controller examples/route-proxy/main.go (routesFrom requires a route's public `name` and treats `internal-name` only as an alias of it)

191 — A route with only an internal name is dropped as naming nothing

What was observed

A module whose endpoint reaches only the private network could not be reached by its internal name. The module ran and answered on its own port. Its route's internal name resolved to the serving node. The request failed during the TLS handshake:

http: TLS handshake error from …: no public route for "unifi.home-server.internal" in this mesh,
  so no certificate is asked for

The proxy's own log said why, every time it re-read its routes:

unifi on home-server asked for a route and named nothing; skipped

The route it skipped was not empty. The mesh had given it an endpoint, a port, a scheme and an internal name, and no public name:

route name internal-name served
home-assistant a public name home-assistant.home-server.internal under both
unifi — unifi.home-server.internal under neither

Three other modules on the same node were skipped with the same line on the same pass.

Why it matters

Reach is decided in one place, and the proxy reads the old shape of the decision. ADR 0138 made an endpoint's reach decide which names exist. The controller composes the public name, the internal name, or both, and composes no name that nobody asked for (issue 140). An endpoint that reaches only the private network is the ordinary case for anything that should not face the internet. It is exactly the case the proxy drops.

The failure is quiet and points the wrong way. Nothing marks the module unhealthy. The handshake error says no public route, which reads as a certificate fault on the reader's side. The line that gives the real cause is one of four identical lines repeated every few seconds in a log nobody reads until they already suspect the proxy.

The opposite move is not a workaround. Giving the endpoint public reach makes the proxy serve it. It also publishes an administration interface to the internet to get a name on the private network.

Open questions

  • Should the proxy refuse a route it cannot serve in a way the controller or an operator sees, not only in its own log? The same silent skip covers a route with no usable port or an unknown scheme.
  • What checks that what the controller composes and what the proxy serves stay the same shape? ADR 0138 changed one side and nothing failed on the other.