Files
hq/04-ISSUES/157-a-routed-names-internal-alias-is-served-by-nothing/00-report.md
T
jschoubben e41eed0852 Issue 129 is live and reproduced, and needs three steps rather than one
The certificate is genuine, from Mesh Internal CA, and nothing on the
workstation trusts it — verbatim the error the report gives. The public
name on the same proxy verifies cleanly, which puts the fault exactly
where the report puts it.

What is in the way is not an assignment. `ca-trust` is merged in the
catalogue and has never been registered with the mesh — 39 of 76
manifests are — so there is no module to assign. It dry-runs clean and
needs no artifact built.

Two findings from reproducing it, both their own issues:

157 — every routed name is published with an `.internal` alias that
nothing serves. The hosts file says keycloak.novox.be.internal; the proxy
serves keycloak.novox.internal and refuses the other by name. The first
three names I tried came from the hosts file and failed with a TLS alert
rather than a verification error, which pointed at a regression that had
not happened.

158 — the proxy re-logs all 52 routes every two seconds, 31 times a
minute. The one line that explained 157 sat between two of them.

Also recorded, because it was nearly filed as a defect and is not one:
step-ca publishes roots as /roots.pem, which is PEM, so ca-trust's fetch
and its refuse-a-non-certificate guard are both right. Its other endpoint
/roots returns JSON that contains the text the guard greps for, so the
guard is sound only because of which path is published.
2026-09-30 01:30:24 +02:00

2.9 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
located 2026-09-30
mesh-controller internal/catalogue/roster.go (the roster's entries for a routed name)

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.