62 lines
2.7 KiB
Markdown
62 lines
2.7 KiB
Markdown
---
|
|
status: located
|
|
opened: 2026-10-01
|
|
located-in: [mesh-controller examples/route-proxy/main.go (routesFrom requires a route's public `name` and treats `internal-name` only as an alias of it)]
|
|
fixed-by:
|
|
amended-design: []
|
|
---
|
|
|
|
# 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](../../02-DECISIONS/0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md)
|
|
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](../140-an-endpoints-reach-is-not-declared/01-resolution.md)). 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.
|