249 Postgres249 Postgres
250</h3>250</h3>
251 251
252El gateway guarda su estado en una base de datos PostgreSQL:
253
254* **Base de datos**: PostgreSQL propiamente dicho, autoalojado o administrado, en la [versión mínima](/docs/es/claude-apps-gateway#prerequisites) o posterior. No se admiten bases de datos que solo implementan el protocolo de Postgres, como las bases de datos SQL distribuidas.
255* **Dirección**: `store.postgres_url` acepta un solo host. Si la base de datos tiene varios nodos, usa la dirección que está delante de ellos, como el endpoint de tu servicio administrado, un balanceador de carga o una IP virtual. Configura un [período de gracia de disponibilidad](#readiness-grace-period) más largo de lo que tarda una conmutación por error.
256
252La puerta de enlace contiene cinco tablas de datos más una tabla `_migrations`, todas creadas por sus migraciones de tiempo de arranque:257La puerta de enlace contiene cinco tablas de datos más una tabla `_migrations`, todas creadas por sus migraciones de tiempo de arranque:
253 258
254| Tabla | Contenidos | Retención |259| Tabla | Contenidos | Retención |
396| CLI `/login`: `Could not resolve the configured HTTP proxy` | El nombre de host en `HTTPS_PROXY` o `HTTP_PROXY` no se resuelve desde la máquina del desarrollador, normalmente porque no está conectada a la red corporativa | Pide al desarrollador que se conecte a tu red o VPN y vuelva a intentarlo, o corrige la URL del proxy |401| CLI `/login`: `Could not resolve the configured HTTP proxy` | El nombre de host en `HTTPS_PROXY` o `HTTP_PROXY` no se resuelve desde la máquina del desarrollador, normalmente porque no está conectada a la red corporativa | Pide al desarrollador que se conecte a tu red o VPN y vuelva a intentarlo, o corrige la URL del proxy |
397| CLI `/login`: `Could not resolve gateway host <host>` | La máquina no puede resolver el nombre DNS interno del gateway, normalmente porque no está en la red corporativa | Pide al desarrollador que se conecte a tu red o VPN y luego reintente `/login` |402| CLI `/login`: `Could not resolve gateway host <host>` | La máquina no puede resolver el nombre DNS interno del gateway, normalmente porque no está en la red corporativa | Pide al desarrollador que se conecte a tu red o VPN y luego reintente `/login` |
398| El arranque sale con un error de validación de configuración que menciona `store.postgres_url` | No hay Postgres configurado; el gateway requiere Postgres | Establece `store.postgres_url`. Para desarrollo local, usa un contenedor desechable: `docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres`. |403| El arranque sale con un error de validación de configuración que menciona `store.postgres_url` | No hay Postgres configurado; el gateway requiere Postgres | Establece `store.postgres_url`. Para desarrollo local, usa un contenedor desechable: `docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres`. |
404| El arranque sale con: `store.postgres_url in <path> is not a URL the gateway can read`, o, antes de v2.1.290, un simple `Invalid URL` o `URI error` | No se puede analizar la URL, por ejemplo porque enumera más de un host o su contraseña tiene un `/`, `?`, `#` o `%` sin codificar | Indica [un solo host](#postgres) y mueve la contraseña a [`store.password`](/docs/es/claude-apps-gateway-config#store) |
399| El arranque sale con: `requires the native binary` | Se está ejecutando con Node en lugar del binario nativo | Instala Claude Code con uno de los [métodos de instalación independiente](/docs/es/setup) |405| El arranque sale con: `requires the native binary` | Se está ejecutando con Node en lugar del binario nativo | Instala Claude Code con uno de los [métodos de instalación independiente](/docs/es/setup) |
400| El arranque sale con un error de descubrimiento OIDC después de `config.load` | `oidc.issuer` no es accesible, o la cadena TLS no es de confianza | Verifica que el emisor sea accesible desde el pod y sirva `/.well-known/openid-configuration`. Establece `ca_cert_pem` para una PKI privada. Si el pod llega al IdP solo a través de un proxy de reenvío, establece [`oidc.use_proxy: true`](/docs/es/claude-apps-gateway-config#idp-requests-through-a-forward-proxy); en versiones anteriores a v2.1.227, dale al pod una ruta directa a cada uno de los endpoints del IdP en su lugar. Si el pod tampoco puede resolver el nombre de host del IdP, o el proxy rechaza `CONNECT` a una dirección IP, consulta [Salida solo por proxy](/docs/es/claude-apps-gateway-config#proxy-only-egress), que requiere v2.1.277 o posterior. |406| El arranque sale con un error de descubrimiento OIDC después de `config.load` | `oidc.issuer` no es accesible, o la cadena TLS no es de confianza | Verifica que el emisor sea accesible desde el pod y sirva `/.well-known/openid-configuration`. Establece `ca_cert_pem` para una PKI privada. Si el pod llega al IdP solo a través de un proxy de reenvío, establece [`oidc.use_proxy: true`](/docs/es/claude-apps-gateway-config#idp-requests-through-a-forward-proxy); en versiones anteriores a v2.1.227, dale al pod una ruta directa a cada uno de los endpoints del IdP en su lugar. Si el pod tampoco puede resolver el nombre de host del IdP, o el proxy rechaza `CONNECT` a una dirección IP, consulta [Salida solo por proxy](/docs/es/claude-apps-gateway-config#proxy-only-egress), que requiere v2.1.277 o posterior. |
401| El arranque sale con un error de permisos de Postgres | El rol de la base de datos no tiene derechos DDL sobre su esquema | Otorga al rol `CREATE` sobre el esquema del gateway para que pueda crear y modificar sus tablas al arrancar |407| El arranque sale con un error de permisos de Postgres | El rol de la base de datos no tiene derechos DDL sobre su esquema | Otorga al rol `CREATE` sobre el esquema del gateway para que pueda crear y modificar sus tablas al arrancar |
402| Registro: `could not connect to Postgres at boot, attempt 1 of 3` | La base de datos aún no era accesible cuando se inició el gateway, por ejemplo en una instancia en frío cuya red todavía se está levantando | Si el gateway luego termina de arrancar, no hace falta hacer nada. Cuando la base de datos no es accesible, el gateway intenta la conexión tres veces, con dos segundos de diferencia, antes de salir. Si sale con `could not connect to Postgres`, revisa `store.postgres_url` y la ruta de red hacia la base de datos. Si se agota el tiempo de espera de los intentos en lugar de ser rechazados, aumenta [`store.connect_timeout_seconds`](/docs/es/claude-apps-gateway-config#store) para darle más tiempo a cada uno. |408| Registro: `could not connect to Postgres at boot, attempt 1 of 3` | La base de datos aún no era accesible cuando se inició el gateway, por ejemplo en una instancia en frío cuya red todavía se está levantando | Si el gateway luego termina de arrancar, no hace falta hacer nada. Cuando la base de datos no es accesible, el gateway intenta la conexión tres veces, con dos segundos de diferencia, antes de salir. Si sale con `could not connect to Postgres`, revisa `store.postgres_url`, incluido que indique un solo host, y la ruta de red hacia la base de datos. Si se agota el tiempo de espera de los intentos en lugar de ser rechazados, aumenta [`store.connect_timeout_seconds`](/docs/es/claude-apps-gateway-config#store) para darle más tiempo a cada uno. |
403| `/oauth/callback` muestra "Sign-in could not be completed" | Dominio de correo electrónico rechazado, falló la validación del id\_token, o `email_verified` es explícitamente `false`, que el gateway siempre rechaza sin posibilidad de sobrescribirlo | Revisa `allowed_email_domains` y que el IdP devuelva un claim `email` verificado. Para `email_verified: false`, corrige la verificación del lado del IdP. Si tu IdP emite el correo electrónico con un nombre de claim diferente, establece `oidc.email_claim`. |409| `/oauth/callback` muestra "Sign-in could not be completed" | Dominio de correo electrónico rechazado, falló la validación del id\_token, o `email_verified` es explícitamente `false`, que el gateway siempre rechaza sin posibilidad de sobrescribirlo | Revisa `allowed_email_domains` y que el IdP devuelva un claim `email` verificado. Para `email_verified: false`, corrige la verificación del lado del IdP. Si tu IdP emite el correo electrónico con un nombre de claim diferente, establece `oidc.email_claim`. |
404| Registro: `token exchange failed request_id=<id>: id_token missing email claim` | El IdP no incluye `email` en el id\_token de forma predeterminada. Este rechazo solo se produce cuando `allowed_email_domains` está establecido; sin él, la falta de correo electrónico genera una sesión sin correo electrónico | Configura el IdP para que emita `email` en el id\_token. Okta: agrega `email` a los claims del token de ID de un servidor de autorización personalizado. Entra: agrega `email` como claim opcional en el registro de la aplicación. PingFederate: habilita una OpenID Connect Policy que emita `email`. Si el IdP sirve `email` desde el endpoint de userinfo pero no lo incluye en el id\_token, como el servidor de autorización de organización de Okta, establece `oidc.userinfo_fallback: true`. |410| Registro: `token exchange failed request_id=<id>: id_token missing email claim` | El IdP no incluye `email` en el id\_token de forma predeterminada. Este rechazo solo se produce cuando `allowed_email_domains` está establecido; sin él, la falta de correo electrónico genera una sesión sin correo electrónico | Configura el IdP para que emita `email` en el id\_token. Okta: agrega `email` a los claims del token de ID de un servidor de autorización personalizado. Entra: agrega `email` como claim opcional en el registro de la aplicación. PingFederate: habilita una OpenID Connect Policy que emita `email`. Si el IdP sirve `email` desde el endpoint de userinfo pero no lo incluye en el id\_token, como el servidor de autorización de organización de Okta, establece `oidc.userinfo_fallback: true`. |
405| Registro: `refresh failed request_id=<id>: invalid_token (…) (at userinfo_no_id_token, …)`, y los desarrolladores ven `Cloud gateway session expired` cada `session.ttl_hours` | El IdP aceptó el token de actualización pero no devolvió ningún id\_token con él, así que el gateway solicitó los claims del usuario al endpoint de userinfo del IdP. El IdP rechazó allí el token de acceso actualizado. El gateway responde `temporarily_unavailable`, por lo que Claude Code conserva el token de actualización pero no puede renovar la sesión. Las versiones del gateway anteriores a v2.1.260 registran la misma línea sin el detalle `(at …)`. | Establece [`oidc.scope_on_refresh: true`](/docs/es/claude-apps-gateway-config#oidc), disponible en el gateway v2.1.260 o posterior, para que la solicitud de actualización pida `openid` de nuevo. Algunos IdP, como Okta, devuelven un id\_token en la actualización solo cuando se solicita. En PingFederate, habilita **Return ID Token On Refresh Grant** en **Applications > OAuth > OpenID Connect Policy Management** en su lugar. La clave no cambia el comportamiento de PingFederate. Para otros IdP que sigan omitiéndolo, verifica si el endpoint de userinfo acepta tokens de acceso emitidos por una actualización. Como solución provisional, aumenta [`session.ttl_hours`](/docs/es/claude-apps-gateway-config#session). Consulta [Configuración del proveedor de identidad](#identity-provider-setup) para conocer la contrapartida en cuanto al desaprovisionamiento. |411| Registro: `refresh failed request_id=<id>: invalid_token (…) (at userinfo_no_id_token, …)`, y los desarrolladores ven `Cloud gateway session expired` cada `session.ttl_hours` | El IdP aceptó el token de actualización pero no devolvió ningún id\_token con él, así que el gateway solicitó los claims del usuario al endpoint de userinfo del IdP. El IdP rechazó allí el token de acceso actualizado. El gateway responde `temporarily_unavailable`, por lo que Claude Code conserva el token de actualización pero no puede renovar la sesión. Las versiones del gateway anteriores a v2.1.260 registran la misma línea sin el detalle `(at …)`. | Establece [`oidc.scope_on_refresh: true`](/docs/es/claude-apps-gateway-config#oidc), disponible en el gateway v2.1.260 o posterior, para que la solicitud de actualización pida `openid` de nuevo. Algunos IdP, como Okta, devuelven un id\_token en la actualización solo cuando se solicita. En PingFederate, habilita **Return ID Token On Refresh Grant** en **Applications > OAuth > OpenID Connect Policy Management** en su lugar. La clave no cambia el comportamiento de PingFederate. Para otros IdP que sigan omitiéndolo, verifica si el endpoint de userinfo acepta tokens de acceso emitidos por una actualización. Como solución provisional, aumenta [`session.ttl_hours`](/docs/es/claude-apps-gateway-config#session). Consulta [Configuración del proveedor de identidad](#identity-provider-setup) para conocer la contrapartida en cuanto al desaprovisionamiento. |