"My route doesn't resolve, returns 502 / 404, or hangs — and I don't know which of the five layers is wrong."
The request flow is browser → DNS → tunnel server → tunnel daemon
→ Caddy → upstream. Any of those five can fail. This page is a
decision tree that isolates the layer in under two minutes.
Run asd doctor first. If it returns ❌ on anything related, fix
that and re-test before walking the tree below — most broken-route
incidents are upstream of the route itself.
$ asd doctor
asd doctor — 6 probe(s) — overall: ❌ fail
❌ Caddy config caddy admin /config/ unreachable
A red Caddy config line is the most common single cause: Caddy
isn't running. asd caddy start fixes it.
If asd doctor is all green, walk the tree.
$ curl -sI http://127.0.0.1:<port>/
HTTP/1.0 200 OK
$ asd caddy list | grep <service>
asd net apply. If still missing: asd net discover to see if$ curl -sI -H "Host: <subdomain>-<id>.<tunnel-host>" http://127.0.0.1:<caddy-http-port>/
HTTP/1.1 200 OK # or 502 / 401 / etc.
(Caddy ports: see asd doctor or asd urls. Usually 80 or a high
port if you don't have root.)
asd caddy config | jq '.apps.http.servers' for the rightendpoint.url in your manifest probablyauthPolicy is in the way.caddy.authBypassPaths.$ asd expose list
NAME PORT URL STATUS
api 4000 https://api-xyz1.eu2.tn.example ✅ healthy
asd net expose start --id=<id> to (re)start it. If it stays unhealthy: asd auth status — the credential set is probably expired.$ curl -sI https://<subdomain>-<id>.<tunnel-host>/
HTTP/2 200
asd auth whoami (wrongasd net discover (thehostRoute.host template).asd net expose start --id=<id>.If you reach this step and everything looks fine, the request reaches
your upstream — the bug is in the upstream's own logic.
The tree is mechanical: each step rules out one layer. By Step 5 the
problem is either fixed or pinpointed to a single component.
To speed up: asd net verify runs many of these checks at once and
returns a per-service pass/fail summary. Use it for quick triage
before walking the tree by hand.
The layers exist because they're orthogonal — DNS, tunnel auth,
Caddy routing, upstream availability all have separate failure modes
and separate diagnostics. Walking them in order isolates the layer
without you having to guess.
The common shortcuts:
| Symptom | First check |
|---|---|
| HTTP 502 Bad Gateway | Step 1 — upstream alive? |
| HTTP 404 | Step 2 — does Caddy have the route at all? |
| HTTP 401 | Step 3 — basic auth / authPolicy is in the way |
| Connection refused | Step 4 — tunnel daemon |
| DNS failure | Step 5 — tunnel server / wrong subdomain |
| Hangs forever | Usually Step 4 (tunnel daemon stuck) |
cookbook/ci-cd-with-asd shows the same checks as a single command.learn/06-custom-routing — flushInterval: -1 and friends.reference/cli/index § net — every diagnostic command.