Valhalla Unavailable
Valhalla answers "can we go from A to B?" (ADR-017). In production it is the shared
valhalla-shared compose project (deploy/valhalla/compose.yaml, deployed by Ansible), reached
by every stack as http://valhalla:8002 on the btp-shared network. It only serves a graph
built out of band; it never builds one. Valhalla is a required dependency: when it is down,
/api/health answers 503 and new trips cannot be routed.
This runbook is the incident path. Building and shipping a graph is planned maintenance: valhalla-routing-graph.md. Empty POI / accommodation / event results are a reference-data gap, not a routing one: see zone-opening.md.
On the VM, define once per session:
alias vh='docker compose -p valhalla-shared -f /opt/bike-trip-planner/deploy/valhalla/compose.yaml'
Locally, use docker compose instead (the valhalla service, profile routing).
Symptoms
/api/healthanswers 503 withdeps.valhalla.status = "down", or routing requests return 5xx- Valhalla logs:
tile not found,unable to load tile,corrupted valhallaexits at boot withNo local PBF files, valhalla_tiles.tar and no tile URLs found: the volume holds no graph- Routes fail outside the built routing perimeter (
deps.reference_data.zones.routing_containment.status = "violated")
Diagnosis
vh ps valhalla
vh logs --tail=200 valhalla
vh exec valhalla curl -sS http://localhost:8002/status | jq
Inspect the tiles volume (valhalla-shared_valhalla-tiles in production):
vh exec valhalla du -sh /custom_files
vh exec valhalla ls -lh /custom_files
A served graph shows valhalla_tiles.tar under /custom_files. Production only needs the tar;
the national extracts it was built from live on the workstation that built it.
Procedure
-
Restart the service first. It only mmaps
valhalla_tiles.tar, so a bad load is often fixed without a rebuild:vh restart valhalla -
Replace the graph when the tiles are genuinely corrupted or missing. Never build on the VM (hours, uncapped memory): re-ship a known-good graph from a workstation that holds one:
make routing-publish deploy@<vm-host> france # the slugs only name the artifactIf the workstation has no graph either, build it first (
make routing-build <slug>..., see valhalla-routing-graph.md). -
Check routing with a known-good request (Lille, inside the France graph), from any app container on
btp-shared:btp-compose exec php curl -sS -X POST http://valhalla:8002/route \ -H 'Content-Type: application/json' \ -d '{"locations":[{"lat":50.63,"lon":3.06},{"lat":50.64,"lon":3.07}],"costing":"bicycle"}'
Verification and follow-up
/api/healthreportsdeps.valhalla.status = "ok"and the overall statusok.- Trigger a trip computation inside the routing perimeter; verify route and stage generation succeed.
- If a graph was rebuilt, note the build runtime in the incident issue (hours for a country:
planned maintenance, not incident downtime), and record any perimeter change in
TRACKING.md.
References
- ADR-017 - Valhalla routing engine
- ADR-049 - zone opening; the routing perimeter must encompass every open zone
- ADR-061 - deployment; the shared
valhalla-sharedproject - valhalla-routing-graph.md - build and ship the routing graph
Makefiletargetsrouting-build,routing-up,routing-publish