# Diagnosis *2026-10-01.* **Ruled out first: the module itself.** Its container was up and had not restarted. The controller's status endpoint answered on its own port with `"up": true`. The tool wrapper beside it was serving all its tools. **Ruled out: name resolution.** The internal name resolved to the serving node's private-network address, which is where the proxy listens. Plain HTTP to the name reached the proxy and got a 404. HTTPS failed in the handshake, and the proxy logged that it had no route for the name. **The route as the proxy received it.** The mesh-written route file held a complete contribution for the module: endpoint `web`, port, scheme `https`, `insecure`, a label, and `internal-name`. It had no `name`. That is what the controller composes for an endpoint whose reach stops at the private network (ADR 0138, `composeName`). The contribution was correct. **Located: `routesFrom` in the proxy.** It reads `name` first and skips the contribution if `name` is empty. It reads `internal-name` only at the end, as a second host for a rule that already has a public one. So the proxy can serve an internal name only next to a public one. That matched the mesh before ADR 0138, when both names were always composed. It has been wrong since then. The other half of the proxy already handles the case. Certificates for a host are split by whether it is in the public set: hosts outside it go to the internal authority, and only hosts inside it are eligible for ACME. A host that is only ever an internal name falls on the correct side of both checks without change. Only reading the route was wrong. **The fix.** `routesFrom` takes a route that names either host, serves each name it carries, and marks only the public one as public. It still skips a route that names neither, with the same log line. A test proves an internal-only route is served, certified by the internal authority, and refused by the public one. That test fails against the code before the change.