Troubleshooting

Every error the OpenWAF Egress gateway returns (401, 403, 404, 413, 502 and more), what causes it and how to fix it.

On this page

Every error the gateway itself returns is JSON with an error code and a message. Errors from the provider are passed through unchanged; the gateway's own always carry one of the codes below. The gateway also logs each refusal on standard output (docker logs openwaf-egress).

{"error": "egress_blocked", "message": "Agent \"my-support-agent\" is not permitted to access target \"openai\""}

All error codes

StatuserrorCause
400body_read_errorThe request body could not be read (client disconnected or broken transfer).
401unauthorized_agentNo agent matches: the name in the URL or in X-OpenWAF-Agent is not in agents, or on /v1/proxy/… no agent has the token sent.
401token_requiredThe agent has a token and the request has no Authorization header.
401invalid_tokenThe Authorization: Bearer value is not the agent's token.
403egress_blockedThe target exists but is not in the agent's allowed_targets.
403ssrf_blockedThe target's host resolves to a private or reserved address, or does not resolve.
403injection_detectedA prompt-injection detector matched the body (enforce_injection).
403data_leak_blockedA data-leak pattern matched the body (block_dlp).
404invalid_routeThe path is not /v1/agent/<agent>/proxy/<target>/…, /v1/proxy/<target>/… or /health.
404unknown_targetThe target alias is not in targets.
413body_too_largeThe body is over 8 MiB, or, with inspection on, its text outside inline media is over 1 MiB.
500invalid_upstream_url, request_creation_failedThe target's base_url cannot be parsed, or the outgoing request cannot be built.
502credential_resolution_failedThe key could not be read from OpenBao or Vault.
502upstream_errorThe provider could not be reached (DNS, connection, TLS or timeout).

401: the agent is not identified

  • unauthorized_agent: check the spelling of <agent> in the base URL against the keys of agents. Names are case-sensitive.
  • token_required: the SDK sends the key in Authorization: Bearer. If it sends it in another header (for example x-api-key), the gateway does not see it.
  • invalid_token: the placeholder in the agent does not match token in the configuration. Remember that a restart is needed after editing the file.

403: the request was refused

egress_blocked: add the target alias to the agent's allowed_targets.

ssrf_blocked: the message says which address was refused, for example destination IP 169.254.169.254 is private or reserved. A provider hostname that resolves to a private address on your network (split DNS, a local proxy) is refused too. A resolution error also lands here: check DNS from inside the container.

injection_detected: the response lists each hit with its detector ID, Label and the matched Snippet:

{"agent":"my-support-agent","detections":[{"ID":"pi.override.en","Label":"Instruction override","Snippet":"Ignore all previous instructions"}],"error":"injection_detected","message":"Request body contains prompt injection or adversarial pattern","target":"openrouter"}

Look at the snippet: it is the text that matched, at most 160 bytes. If it came from a document or a web page the agent read, the agent is doing its job by not acting on it. Detectors cannot be turned off one by one in v0.1.1; for an agent that must process such text, set enforce_injection to false for that agent only.

data_leak_blocked: the response lists each type (credit_card, private_key, api_key) with a description. Card numbers are shown with the first and last four digits only. Remove the data from the prompt, or set block_dlp to false for that agent.

413: the body is too large

The gateway never cuts a body and never forwards part of it uninspected. With enforce_injection or block_dlp on, the text must fit 1 MiB. Inline media does not count: data:image/…;base64,… URIs (audio and video too) and JSON "data" members of at least 1 KiB of bare base64 (OpenAI input_audio, Gemini inlineData, Anthropic base64 sources). Send large files by URL or through the provider's file API, or split the request. No body may exceed 8 MiB.

502: OpenBao or the provider failed

credential_resolution_failed: the log line says which secret failed, without its value:

[EGRESS] Failed resolving secret agents/support:OPENROUTER_API_KEY for agent my-support-agent: vault error 403 reading agents/support
  • obtaining vault token: approle login failed with status …: wrong role_id or secret_id, or the secret ID expired.
  • vault error 403: the AppRole policy does not allow read on <kv_mount>/data/<path>, often because kv_mount or path is wrong. With KV v2 the mount is not part of path.
  • vault error 404: there is no secret at that path.
  • key "…" not found in path "…": the secret exists but has no field with that name.
  • A connection or certificate error: check addr and ca_file, and that /health reports "openbao": true.

upstream_error: the message includes the error. Check the target's base_url, DNS and outbound access from the container. The gateway waits up to 5 minutes for the provider's response headers and 15 minutes for a whole exchange, streamed body included.

The provider answers 401 or 403

The error comes from the provider, passed through. Usual causes:

  • The target has no entry in the agent's credential_mapping, so the request reached the provider without a key.
  • The key in OpenBao is wrong, revoked or rotated less than five minutes ago (the gateway caches secrets for five minutes).
  • The target's auth_header or auth_prefix does not match what the provider expects (Anthropic: x-api-key with no prefix; Gemini: x-goog-api-key). Keys in the query string (?key=) are not injected.

The agent gets a 3xx

The gateway does not follow redirects; the provider's 3xx reaches the agent as it is. Point base_url at the final URL the provider documents (for example https:// instead of http://).

/health says "openbao": false

Either openbao.addr is not set, or the gateway could not get 200 or 429 from <addr>/v1/sys/health within three seconds: the server is sealed or unreachable, or its certificate is not trusted (set ca_file). Requests to targets with a credential_mapping will fail with 502 until it is fixed.

Written from github.com/openwaf-dev/[email protected] (external link).

Last updated:

↑↓ to navigate↵ to openesc to close