Cada error que devuelve la propia pasarela es JSON con un código en error y un message (en inglés). Los errores del proveedor llegan sin cambios; los de la pasarela llevan siempre uno de los códigos de abajo. La pasarela también escribe cada rechazo en la salida estándar (docker logs openwaf-egress).
{"error": "egress_blocked", "message": "Agent \"my-support-agent\" is not permitted to access target \"openai\""}Todos los códigos de error
| Estado | error | Causa |
|---|---|---|
| 400 | body_read_error | No se pudo leer el cuerpo de la petición (el cliente se desconectó o la transferencia se cortó). |
| 401 | unauthorized_agent | Ningún agente coincide: el nombre de la URL o de X-OpenWAF-Agent no está en agents o, en /v1/proxy/…, ningún agente tiene el token enviado. |
| 401 | token_required | El agente tiene token y la petición no lleva cabecera Authorization. |
| 401 | invalid_token | El valor de Authorization: Bearer no es el token del agente. |
| 403 | egress_blocked | El destino existe pero no está en los allowed_targets del agente. |
| 403 | ssrf_blocked | El host del destino resuelve a una dirección privada o reservada, o no resuelve. |
| 403 | injection_detected | Un detector de inyección de prompt ha saltado con el cuerpo (enforce_injection). |
| 403 | data_leak_blocked | Un patrón de fuga de datos ha saltado con el cuerpo (block_dlp). |
| 404 | invalid_route | La ruta no es /v1/agent/<agente>/proxy/<destino>/…, /v1/proxy/<destino>/… ni /health. |
| 404 | unknown_target | El alias del destino no está en targets. |
| 413 | body_too_large | El cuerpo pasa de 8 MiB o, con la inspección activada, su texto fuera de los medios en línea pasa de 1 MiB. |
| 500 | invalid_upstream_url, request_creation_failed | La base_url del destino no se puede interpretar, o no se puede construir la petición de salida. |
| 502 | credential_resolution_failed | No se pudo leer la clave de OpenBao o Vault. |
| 502 | upstream_error | No se pudo llegar al proveedor (DNS, conexión, TLS o tiempo agotado). |
401: el agente no se identifica
unauthorized_agent: compara el<agente>de la URL base con las claves deagents. Se distinguen mayúsculas y minúsculas.token_required: el SDK tiene que enviar la clave enAuthorization: Bearer. Si la envía en otra cabecera (por ejemplox-api-key), la pasarela no la ve.invalid_token: el marcador del agente no coincide con eltokende la configuración. Recuerda que hay que reiniciar después de editar el fichero.
403: la petición se ha rechazado
egress_blocked: añade el alias del destino a los allowed_targets del agente.
ssrf_blocked: el mensaje dice qué dirección se ha rechazado, por ejemplo destination IP 169.254.169.254 is private or reserved. Un nombre del proveedor que en tu red resuelve a una dirección privada (DNS partido, un proxy local) también se rechaza. Un error de resolución acaba aquí igualmente: revisa el DNS desde dentro del contenedor.
injection_detected: la respuesta enumera cada detección con el ID del detector, su Label y el Snippet encontrado:
{"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"}Mira el fragmento: es el texto que ha saltado, de 160 bytes como mucho. Si venía de un documento o una página web que leyó el agente, la pasarela ha hecho su trabajo al no dejarlo pasar. En la v0.1.1 los detectores no se pueden desactivar de uno en uno; para un agente que tenga que procesar ese tipo de texto, pon enforce_injection a false solo en ese agente.
data_leak_blocked: la respuesta enumera cada type (credit_card, private_key, api_key) con una descripción. Los números de tarjeta solo se muestran con los cuatro primeros y los cuatro últimos dígitos. Quita esos datos del prompt, o pon block_dlp a false en ese agente.
413: el cuerpo es demasiado grande
La pasarela nunca recorta un cuerpo ni reenvía una parte sin inspeccionar. Con enforce_injection o block_dlp activados, el texto tiene que caber en 1 MiB. Los medios en línea no cuentan: las URI data:image/…;base64,… (también de audio y vídeo) y los miembros JSON "data" con al menos 1 KiB de base64 (input_audio de OpenAI, inlineData de Gemini, fuentes base64 de Anthropic). Envía los ficheros grandes por URL o con la API de ficheros del proveedor, o divide la petición. Ningún cuerpo puede pasar de 8 MiB.
502: falla OpenBao o el proveedor
credential_resolution_failed: la línea del registro dice qué secreto ha fallado, sin su valor:
[EGRESS] Failed resolving secret agents/support:OPENROUTER_API_KEY for agent my-support-agent: vault error 403 reading agents/supportobtaining vault token: approle login failed with status …:role_idosecret_idincorrectos, o el ID secreto ha caducado.vault error 403: la política del AppRole no permitereadsobre<kv_mount>/data/<path>, a menudo porquekv_mountopathestán mal. Con KV v2 el montaje no forma parte depath.vault error 404: no hay ningún secreto en esa ruta.key "…" not found in path "…": el secreto existe pero no tiene un campo con ese nombre.- Un error de conexión o de certificado: revisa
addryca_file, y que/healthdiga"openbao": true.
upstream_error: el mensaje incluye el error. Revisa la base_url del destino, el DNS y la salida a internet del contenedor. La pasarela espera hasta 5 minutos las cabeceras de respuesta del proveedor y 15 minutos un intercambio entero, con el cuerpo en streaming.
El proveedor responde 401 o 403
El error es del proveedor y llega tal cual. Causas habituales:
- El destino no tiene entrada en el
credential_mappingdel agente, así que la petición llegó al proveedor sin clave. - La clave de OpenBao es incorrecta, está revocada o se rotó hace menos de cinco minutos (la pasarela guarda los secretos en caché cinco minutos).
- La
auth_headero elauth_prefixdel destino no son los que espera el proveedor (Anthropic:x-api-keysin prefijo; Gemini:x-goog-api-key). Las claves en la cadena de consulta (?key=) no se inyectan.
El agente recibe un 3xx
La pasarela no sigue redirecciones; el 3xx del proveedor llega al agente tal cual. Apunta base_url a la URL final que documenta el proveedor (por ejemplo https:// en lugar de http://).
/health dice "openbao": false
O no hay openbao.addr, o la pasarela no ha recibido 200 ni 429 de <addr>/v1/sys/health en tres segundos: el servidor está sellado o no se llega a él, o su certificado no es de confianza (pon ca_file). Las peticiones a destinos con credential_mapping fallarán con 502 hasta que se arregle.
Escrito a partir de github.com/openwaf-dev/[email protected] (enlace externo).