Errors¶
The codes and messages kubelatch returns, what they mean, and what to do about each one. The messages are in Spanish and are shown as-is in kubectl and in the interface.
Proxy errors¶
The proxy (/clusters/<id>/...) always responds with a Kubernetes Status object, so kubectl shows the message directly:
{"kind": "Status", "apiVersion": "v1", "status": "Failure", "message": "credencial revocada", "reason": "Unauthorized", "code": 401}
Every response carries the Audit-ID header. If you open an issue, include that value.
| Code | Message | What it means | What to do |
|---|---|---|---|
400 |
ruta no válida: segmentos vacíos, '.' o '..' o caracteres escapados no están permitidos (invalid route: empty segments, '.' or '..', or escaped characters are not allowed) |
The route has //, ., .., an escape or a %. |
Check the kubeconfig's server: it must be https://<kubelatch>/clusters/<id>, nothing else. |
400 |
identificador de cluster no válido: … (invalid cluster identifier: …) |
The segment after /clusters/ cannot be a cluster's id. |
Use the kubeconfig kubelatch gave you. |
400 |
kubelatch no admite cabeceras Impersonate-* (kubectl --as no está soportado) (kubelatch does not support Impersonate-* headers (kubectl --as is not supported)) |
You used --as, --as-group, or a tool that uses impersonation. |
Remove --as. If you need to test someone else's permissions, use the cluster's native admin access. |
401 |
hace falta un token de kubelatch (Authorization: Bearer klt_...) (a kubelatch token is required (Authorization: Bearer klt_...)) |
There's no token, or it doesn't have the format of a kubelatch token. | Check that the kubeconfig has the full token. |
401 |
credencial desconocida (unknown credential) |
The token doesn't exist in kubelatch (miscopied, from another installation, or its cluster was deleted). | Issue a new credential. |
401 |
credencial revocada (credential revoked) |
Someone revoked the credential. | Issue a new one; if it wasn't you, tell an admin. |
401 |
credencial caducada (credential expired) |
It passed its expiry date. | Renew the credential. |
403 |
la cuenta está deshabilitada (the account is disabled) |
The account that owns the credential is disabled. | Talk to an admin. |
403 |
esta credencial está restringida al cluster <id> (this credential is restricted to cluster |
The credential was issued for another cluster. | Use the correct context or issue a credential for this cluster. |
403 |
user:<login> no tiene permisos activos en el cluster <id> (user: |
You have no permission currently in effect in that cluster (never had one, it was revoked, or it expired). | Ask an admin for the permission. |
403 |
la credencial ya no es válida: revocada, caducada, cuenta deshabilitada o permisos cambiados (the credential is no longer valid: revoked, expired, account disabled, or permissions changed) |
The request was in progress and got cut off because something changed. | Retry it; if it keeps failing, check the rows above. |
404 |
cluster desconocido (unknown cluster) |
There's no cluster with that id. | Check the kubeconfig's server. |
500 |
error interno (internal error) |
Unexpected kubelatch failure. | Look up the Audit-ID in kubelatch's log. |
502 |
no se pudo hablar con el API server del cluster: tiempo de espera agotado (could not reach the cluster's API server: timed out) |
The API server didn't respond in time. | An admin must check the network between kubelatch and the cluster. |
502 |
no se pudo hablar con el API server del cluster: el certificado del API server no coincide con la CA registrada (could not reach the cluster's API server: the API server's certificate doesn't match the registered CA) |
The API server's certificate changed or isn't the registered one. | An admin reruns the one-liner with the cluster's current kubeconfig (it brings the new CA) and pastes the JSON into Volver a pegar tokens (Paste tokens again). |
502 |
no se pudo hablar con el API server del cluster: API server inalcanzable (could not reach the cluster's API server: API server unreachable) |
Connection refused, name not resolved, or network unreachable. | An admin checks the cluster's URL and network path (see Private clusters). |
502 |
no se pudo hablar con el API server del cluster: error de conexión (could not reach the cluster's API server: connection error) |
Another connection failure. | The full detail is in kubelatch's log. |
503 |
el cluster todavía no tiene tokens configurados (the cluster doesn't have tokens configured yet) |
The cluster is registered but the bootstrap JSON hasn't been pasted yet. | An admin finishes registering the cluster. |
503 |
kubelatch no puede consultar su base de datos (kubelatch cannot query its database) |
Postgres isn't responding, or (if it only happens on one cluster) its tokens can't be decrypted because KUBELATCH_ENCRYPTION_KEY changed; the log says proxy: load cluster. |
An admin checks Postgres or re-pastes the cluster's tokens. |
503 |
kubelatch no puede registrar la petición (kubelatch cannot record the request) |
The audit row couldn't be written; without it, the request isn't forwarded. | An admin checks Postgres. |
503 |
kubelatch se está reiniciando (kubelatch is restarting) |
The replica is shutting down (a rollout). | Retry: kubectl and client-go do this on their own. |
A 403 with an English-language message like User "user:<login>" cannot list resource "secrets"… is not from kubelatch: it's the cluster's RBAC saying your tier doesn't include that action (see Tiers).
Statuses you'll only see in the audit log¶
| Status | Error | What it means |
|---|---|---|
101 |
An upgraded connection (exec, attach, port-forward, cp). The row is completed when it closes. |
|
101 |
stream cortado: la credencial ya no es válida (stream cut: the credential is no longer valid) |
An open stream that kubelatch cut off when revoking, expiring, disabling, or changing permissions. |
499 |
cliente desconectado (client disconnected) |
The client hung up before receiving the response. |
| any | kubelatch reiniciando (kubelatch restarting) |
The stream was cut because the replica was shutting down. |
Errors signing in with GitHub¶
When login with GitHub fails, kubelatch redirects to /login?error=<code> (or to /mi-cuenta?error=<code> if you were linking from Mi cuenta (My account)), and the page shows the message from the table. Each code has an anchor #github-<code>.
An unknown code shows No se pudo entrar con GitHub. (Could not sign in with GitHub.). Almost every failure leaves a login.failure with the code in the control plane's log; the state ones from a missing, expired, or other-session cookie, and the server ones, only stay in the log. How to resolve each case is in If something fails and in Troubleshooting.
API errors¶
Under /api/, errors are JSON with a single field:
{"error": "sesión caducada o no válida"}
| Code | Common messages | What it means |
|---|---|---|
400 |
cuerpo JSON no válido (invalid JSON body); the specific reason for a validation (el namespace kube-system está protegido: … (namespace kube-system is protected: …), ttl no válido: usa por ejemplo 7d o 12h (invalid ttl: use for example 7d or 12h), …) |
Malformed request or one that doesn't meet policy. |
401 |
sesión no iniciada (no session started); sesión caducada o no válida (session expired or invalid); usuario o contraseña incorrectos (incorrect user or password) |
The session is missing, expired, or was revoked; or the login failed (the message is the same for any reason). |
403 |
solo para administradores (administrators only); petición de otro origen rechazada (cross-origin request rejected); esta cuenta entra con GitHub: no usa contraseña (this account signs in with GitHub: it doesn't use a password); solo un administrador puede operar sobre credenciales de otros (only an administrator can operate on other people's credentials); solo puedes consultar tus propios permisos (you can only view your own permissions) |
The role is missing, the request comes from another origin, or the action isn't allowed for that account. |
404 |
no encontrado (not found); usuario no encontrado (user not found); cluster no encontrado (cluster not found); enlace no válido (invalid link); el acceso con GitHub no está configurado (GitHub login isn't configured) |
The resource doesn't exist (or isn't yours). |
405 |
método no permitido (method not allowed) |
Known route, unsupported method. The Allow header says which ones are valid. |
409 |
ese permiso ya existe (that permission already exists); ese login ya existe (los logins no se reutilizan) (that login already exists (logins are never reused)); no se puede quitar ni deshabilitar al último administrador activo (the last active administrator cannot be removed or disabled); sin permisos activos: no hay ningún cluster al que dar acceso (no active permissions: there's no cluster to grant access to); ya hay una reconciliación de este cluster en curso (a reconciliation of this cluster is already in progress); el cluster no tiene tokens todavía: … (the cluster doesn't have tokens yet: …) |
Conflict with the current state. |
410 |
el enlace ha caducado o ya se ha usado; pide uno nuevo a un administrador (the link has expired or was already used; ask an administrator for a new one) |
Invitation or linking link spent, expired, or revoked. |
413 |
cuerpo demasiado grande (body too large) |
More than 64 KiB. |
429 |
demasiados intentos (too many attempts) |
Account locked for 15 minutes after 5 failures, or a limit of 10 attempts per minute per IP. |
500 |
error interno (internal error) |
Unexpected failure; the detail is in the log. |
502 |
A summary of the cluster's failure | Listing a cluster's namespaces, granting a permission, or reconciling needed to talk to the cluster and couldn't. |
503 |
el intercambio de CI no está configurado (the CI exchange isn't configured); el reconciliador no está disponible (the reconciler isn't available) |
An internal piece isn't available. |
CI exchange¶
POST /v1/ci/github-actions/token uses the same {"error": "…"} format:
| Code | Message | What to do |
|---|---|---|
401 |
token no válido (invalid token) |
Any problem with the token itself: signature, expiry, audience, issuer, reuse. The exact reason is in the log and in the ci.exchange.failure event. Check that the audience is your KUBELATCH_BASE_URL. |
403 |
ninguna trust rule coincide con este workflow (repository_owner_id=… repository_id=… ref=… environment=…): … (no trust rule matches this workflow (repository_owner_id=… repository_id=… ref=… environment=…): …) |
An admin must create the trust rule with those ids. |
403 |
el bot <bot> de la trust rule «<regla>» está deshabilitado (bot |
An admin re-enables the bot. |
403 |
el bot <bot> no tiene permisos activos en ningún cluster: … (bot |
An admin grants the bot permissions. |
429 |
demasiados intentos (too many attempts) |
More than 60 requests per minute from the same IP. |
A token rejected by policy (403) is not spent: the workflow can retry once the admin fixes the configuration.
GitHub webhook¶
POST /v1/github/webhook responds 404 without GITHUB_WEBHOOK_SECRET, 401 firma no válida (invalid signature) if the secret doesn't match, 415 if the content type isn't application/json, 413 with more than 1 MiB, and 400 if the body isn't JSON. A member_removed for the last administrator who can sign in responds 200 but doesn't disable anyone: check the log.