This page maps symptoms to causes and fixes. Two tools solve most incidents: rerun with RUST_LOG=debug and read the error chain (each caused by: line narrows it down), and query the admin interface to see what the process actually loaded.
Arion refuses to start on my Envoy config
This is deliberate. Arion validates every field and refuses configuration it cannot honor, instead of silently ignoring it — the error names the exact path:
failed to deserialize ... listeners[0].filter_chains[0] ...
caused by:
Unsupported field: use_original_dst
Remove or replace the named field. Unsupported enum variant means the field exists but that value does not (an unsupported filter's @type, for example). The supported configuration reference lists what converts; anything outside it must come out of the file before Arion will run it.
"secret doesn't contain server name"
Your TLS certificate has no DNS name in its Subject Alternative Name extension. Arion takes the server name from the SAN (not the CN) to match SNI, so a SAN-less certificate is unusable. Regenerate it with a SAN — certificates cannot be amended after signing:
openssl x509 -in server-cert.pem -text -noout | grep -A2 "Subject Alternative Name"
If that prints nothing, reissue the certificate with subjectAltName = DNS:api.example.com and make sure the listener's filter_chain_match.server_names matches one of the SAN entries.
The private key or certificate is rejected
Three frequent causes: the certificate_chain block contains BEGIN PUBLIC KEY instead of BEGIN CERTIFICATE; certificate and key are swapped between the two fields; or the key is PKCS#1 (BEGIN RSA PRIVATE KEY) while Arion expects PKCS#8 (BEGIN PRIVATE KEY). Convert with:
openssl pkcs8 -topk8 -nocrypt -in pkcs1-key.pem -out pkcs8-key.pemTLS works, but the wrong certificate is served
The client's SNI selects the filter chain. Test what a given name gets: openssl s_client -connect host:8443 -servername api.example.com. If the default chain answers, no filter_chain_match.server_names entry matched the SNI — check for exact-name versus wildcard mismatches, and remember %REQUESTED_SERVER_NAME% in an access log shows what clients actually sent.
Connection refused on my listener
The listener is not bound where you are connecting. Check curl http://127.0.0.1:9901/listeners for the live name::address list. Usual causes: the listener binds 127.0.0.1 while you connect from outside (bind 0.0.0.0 in containers), the container port is not published, or the process is not running at all — configuration Arion cannot honor stops it at startup, so read the log before anything else.
Upstream 5xx / no healthy endpoints
A 503 produced by Arion itself (rather than the backend) usually means no usable endpoint: the access-log operators %RESPONSE_CODE_DETAILS% and %RESPONSE_FLAGS_LONG% show no_healthy_upstream / NoHealthyUpstream when health checks have marked everything down, and UpstreamConnectionFailure when connects fail. Check curl http://127.0.0.1:9901/clusters for per-endpoint health and failure counters. If endpoints show connect failures, verify they are reachable from the gateway host and that connect_timeout is realistic. 504s point at response timeouts instead — see the route timeout before blaming the backend.
JWT-protected requests always get 401
The token is being rejected, and the reasons are almost always one of: the token's iss claim does not exactly match the provider's issuer; the token's aud is not in audiences; or the JWKS is not available — for remote_jwks, the cluster it points at must be reachable so keys can be fetched (a fetch failure leaves no keys to validate with; a local_jwks file removes that dependency). Decode the token's claims, compare them character-for-character with the JWT configuration, and rerun with RUST_LOG=debug to see which check fails.
xDS is connected, but updates never apply
Your control plane may be receiving NACKs. Search the Arion log for rejecting configs with nack response — the message lists each rejected resource and why (typically an unsupported field, as at startup). Decoding or conversion failures leave that response unapplied; later application failures can leave some changes applied. Check the admin interface and verify traffic before retrying a corrected configuration. See xDS control planes.
An admin or metrics endpoint returns 404
/config_dump, /stats and /stats/prometheus exist only in binaries built with the config-dump, metrics and prometheus features respectively — the same applies to access logging (access-log), tracing (tracing) and WASM (wasm). curl http://127.0.0.1:9901/help lists exactly what your build contains; if the endpoint is missing there, rebuild with the feature rather than debugging configuration.