Files
hq/04-ISSUES/157-a-routed-names-internal-alias-is-served-by-nothing/00-report.md
T
jschoubben 04c9500b5b Group 2 is resolved: containers resolve, nothing is copied, a route's name says where it arrives
Issue 110's cause was not the filter: the runtime had never been told,
and the resolver dropped a query arriving on a bridge. ADR 0148 step 3
landed once it did (109, 151 resolved). ADR 0151 composes a route's
internal name under the serving node and drops the suffixed alias
(139, 157 resolved). Design 08 amended; a fact in 0148 corrected.
2026-09-30 14:56:43 +02:00

3.4 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
resolved 2026-09-30
mesh-controller internal/catalogue/roster.go (the roster's entries for a routed name)
mesh-controller PR 163 — a routed name is published as itself, once, with no suffixed alias (ADR 0151, 2026-09-30)

157 — A routed name is published with an .internal alias that nothing serves

What was observed

Every machine's hosts file carries two entries for each routed name — the name, and the name with .internal appended:

10.10.0.1	keycloak.novox.be.internal	keycloak.novox.be
10.10.0.1	drive.novox.be.internal	drive.novox.be
10.10.0.1	umami.novox.be.internal	umami.novox.be

The suffixed one resolves and is served by nothing. The proxy refuses it during the handshake, and says so exactly:

http: TLS handshake error from 10.10.0.3:33480:
  no public route for "keycloak.novox.be.internal" in this mesh, so no certificate is asked for

A client sees curl: (35) TLS connect error ... tlsv1 alert internal error and no peer certificate — a server-side refusal, with nothing in it to say the name was never real.

The name the proxy does serve is <label>.<node>.internal — keycloak.novox.internal — which is what issue 139 describes. So there are two internal shapes for one service, one of them composed by appending the suffix to a name that already has a domain.

Why it matters

It sends a reader to the wrong diagnosis. Reproducing issue 129 on 2026-09-30, the first three names tried came from the hosts file, all failed with a TLS alert rather than the verification error 129 reports, and the evidence pointed at the proxy having lost its internal certificates — a regression that had not happened. The correct name reproduces 129 exactly. Several minutes went into a fault that did not exist, and the only thing that distinguished the two was reading the proxy's own log.

It is also a name in every machine's hosts file, and in every container's, that cannot be reached: the shape the mesh is otherwise careful about — writing a name that resolves to something that does not answer is worse than not writing it, because a connection to an address that does not answer hangs where a name that does not resolve fails at once (ADR 0007, and the same reasoning in namesInTheMesh).

Where to look

The roster template renders one entry per name as {{.FQDN}} {{.Name}}, and FQDN is composed by appending the mesh suffix to the bare name. For a node that is right — novox becomes novox.internal. For a routed name the bare name is already a fully qualified public name, so the composition produces keycloak.novox.be.internal, which is not a name anything was told to serve.

The fix is a judgement about what a routed name's internal form is, and 139 is the record that asks it; this one is the evidence that the current answer publishes a third thing that is neither.

Resolved (2026-09-30)

The judgement 139 asked for is ADR 0151: a routed name has no mesh form. The roster now publishes it as itself, once, at the serving node's address; the <domain>.internal line is gone from every machine's hosts file, and a controller test refuses it coming back.