Un 403 PERMISSION_DENIED de Gemini API no significa «vuelve a intentarlo más tarde». Primero identifica qué acción fue rechazada: crear una clave en Google AI Studio, llamar a Gemini Developer API, generar dentro de AI Studio o acceder a un modelo o cliente que utiliza otro contrato de autenticación. Antes de tocar nada, guarda el HTTP status, mensaje exacto, hostname del endpoint, project seleccionado, model, timestamp y request ID. Nunca guardes ni envíes la clave completa.
| Dónde falla | Primera comprobación segura | Qué no hacer todavía |
|---|---|---|
| AI Studio no puede crear una clave | Confirmar que el project está importado y consultar resourcemanager.projects.get e iam.serviceAccountApiKeyBindings.create con el administrador | No conceder Owner por una sola operación |
models.list y todas las llamadas devuelven 403 | Probar qué variable está activa, a qué project pertenece la clave y si las restricciones API/aplicación coinciden | No rotar varias claves seguidas |
| La lista funciona, pero la generación devuelve 403 | Revisar model path, action, endpoint, auth de tuned model y policy de project/account | No confundir visibilidad con permiso de generación |
| AI Studio muestra blocked, suspicious o permission denied | Confirmar account conectado y project seleccionado; conservar texto y hora | No inferir suspensión por un caso de foro |
Comprueba la presencia de variables sin imprimir el secreto:
bashprintf 'GOOGLE_API_KEY=%s\n' "${GOOGLE_API_KEY:+set}" printf 'GEMINI_API_KEY=%s\n' "${GEMINI_API_KEY:+set}"
Si existen ambas, la documentación actual de las client libraries de Google da prioridad a GOOGLE_API_KEY. Después de confirmar endpoint y project, ejecuta dos canaries con la misma credencial: listar modelos y, a continuación, una generación mínima. Si falla la lista, mantente en la rama clave/project/estado/restricción/endpoint. Si la lista funciona y la generación falla, pasa a model/action/authentication. Si ambas funcionan, compara local y deployment configuration.
Deja de crear claves o projects cuando los canaries limpios repitan el rechazo o AI Studio muestre blocked/suspicious a nivel de account con objetos correctos. Prepara para el administrador o Google un error sanitizado, project ID, fingerprint corto de la clave, endpoint, model, timestamp, request ID y resultados de ambos canaries.
El mismo 403 puede pertenecer a responsables distintos
Una API key es una credencial asociada a un Google Cloud project. No es por sí misma IAM policy, billing account, quota bucket, autorización para el modelo, endpoint ni account conectado en AI Studio. «La clave existe» o «funcionaba ayer» no demuestra que la acción actual esté permitida.
La guía actual de solución de problemas de Gemini API define 403 PERMISSION_DENIED como una clave que carece de permisos requeridos. Incluye ejemplos de wrong key y tuned model sin autenticación correcta. La misma guía aconseja no reintentar client errors como 400 y 403. Un retry cambia el tiempo, pero no cambia la credencial, la restriction ni la autorización del recurso.
La portada de Google en español mezcla ayuda de AI Studio, GitHub bugs, n8n, errores de caching, cuentas personales y guías generales de 403. Esos resultados describen síntomas reales, pero no comparten necesariamente propietario. Un wrapper puede ocultar la clave activa o el endpoint, y un caso de account no demuestra una suspensión universal. La pregunta útil es qué acción falló y quién controla esa acción.

| Acción rechazada | Responsable probable | Evidencia que acota | Siguiente movimiento mínimo |
|---|---|---|---|
| Crear clave en AI Studio | Project import, IAM, organization policy, service-account binding | Texto UI, project ID, account, missing permission | Pedir el permiso mínimo o usar un project propio legítimo |
| Listar modelos | Clave activa, owning project, API/application restriction, endpoint | Variable, fingerprint, hostname, status, body sanitizado | Corregir un desajuste y repetir el list canary |
| Generar contenido | Model/action authorization, tuned-model auth, project/account policy | Resultado de lista, model path, generation status, request ID | Probar una base model actual en la misma ruta |
| Generar dentro de AI Studio | Signed-in account, project seleccionado, AI Studio enforcement | Mensaje UI, project, hora | No cambiar objetos hasta conocer ownership |
| Funciona local, falla deployment | Deployed secret, env precedence, IP/origin restriction, stale revision | Fingerprints, revision, egress IP/origin | Actualizar solo el secret o restriction que no coincide |
Conserva el error antes de rotar la clave o ampliar IAM
El primer failed request suele ser la evidencia más limpia. Antes de rotar, cambiar project, editar restrictions o desplegar de nuevo, registra:
- UTC timestamp y timezone local;
- HTTP status, status name y response body sanitizado;
- endpoint hostname, API version y method;
- model o resource path;
- project ID;
- SDK/client version;
- request ID, trace ID o correlation ID si aparece;
- si ocurre en AI Studio, local, CI o production;
- si
models.listy elgenerateContentmínimo se comportan de forma distinta.
No adjuntes la clave completa, screenshots con el secreto, environment dump completo, cookies, OAuth tokens, service-account JSON, secretos sin relación o un production payload privado.
Un fingerprint unidireccional permite comparar local, CI y production:
bashif [ -n "${GOOGLE_API_KEY:-}" ]; then ACTIVE_KEY="$GOOGLE_API_KEY" KEY_SOURCE="GOOGLE_API_KEY" elif [ -n "${GEMINI_API_KEY:-}" ]; then ACTIVE_KEY="$GEMINI_API_KEY" KEY_SOURCE="GEMINI_API_KEY" else echo "Gemini API key variable is not set" exit 1 fi printf 'source=%s length=%s sha256=' "$KEY_SOURCE" "${#ACTIVE_KEY}" printf '%s' "$ACTIVE_KEY" | shasum -a 256 | cut -c1-12
El prefijo hash de 12 caracteres no es la clave. Sirve para demostrar si dos entornos leen el mismo secret. Aun así, mantenlo en el incident interno o en un support channel seguro, no en un issue público.
Dos canaries separan acceso básico de autorización de acción
Mantén iguales credential, project y endpoint. Cambia solo el desajuste señalado por la evidencia y vuelve a ejecutar las mismas pruebas.

Canary 1: listar modelos
Gemini Developer API utiliza generativelanguage.googleapis.com. Este ejemplo pasa la clave mediante un descriptor de header y guarda el body en un archivo temporal local:
bashLIST_HTTP=$( curl --silent --show-error \ --output /tmp/gemini-models.json \ --write-out '%{http_code}' \ --header @<(printf 'x-goog-api-key: %s\n' "$ACTIVE_KEY") \ 'https://generativelanguage.googleapis.com/v1beta/models' ) printf 'models.list HTTP %s\n' "$LIST_HTTP" jq '{error, model_count: (.models | length?)}' /tmp/gemini-models.json
Un 403 aquí mantiene el diagnóstico en active key, project, key state, restriction o endpoint. Un 200 con modelos demuestra baseline access, no acceso a todas las acciones. Un 404 o JSON inesperado exige revisar hostname, API version, proxy/base URL y construcción del request. Un 429 ya pertenece a quota/rate limit.
Canary 2: generación mínima
Elige del list response un model path actual que declare soporte para generateContent. No copies un model ID antiguo. Revisa pricing y eligibility actuales porque el canary sigue siendo una llamada real.
bashMODEL_PATH='models/<modelo-actual-de-la-lista-con-generateContent>' GEN_HTTP=$( curl --silent --show-error \ --output /tmp/gemini-generate.json \ --write-out '%{http_code}' \ --request POST \ --header @<(printf 'x-goog-api-key: %s\n' "$ACTIVE_KEY") \ --header 'Content-Type: application/json' \ --data '{"contents":[{"parts":[{"text":"Responde solo OK."}]}]}' \ "https://generativelanguage.googleapis.com/v1beta/${MODEL_PATH}:generateContent" ) printf 'generateContent HTTP %s\n' "$GEN_HTTP" jq '{error, candidates: (.candidates | length?)}' /tmp/gemini-generate.json
| Lista | Generación | Interpretación |
|---|---|---|
| 403 | No ejecutar | Rechazo previo a model action: key, project, state, restriction o endpoint |
| 200 | 403 | Baseline funciona; revisar model/action auth, tuned resource y project/account policy |
| 200 | 404 | No coincide model path, API version o disponibilidad en la ruta |
| 200 | 429 | Permission funciona; corresponde a quota, tier o traffic shape |
| 200 | 200 | Ruta básica correcta; comparar app code, deployed secret, headers, proxy y region |
Después de guardar resultados sanitizados, elimina archivos y variable temporal:
bashrm -f /tmp/gemini-models.json /tmp/gemini-generate.json unset ACTIVE_KEY
Cuando AI Studio no permite crear una clave en el project
Ese rechazo ocurre antes de que la aplicación tenga una clave utilizable. Cambiar generateContent, model names o retry logic no puede solucionarlo.
La guía actual de claves de Gemini API indica que cada clave pertenece a un Google Cloud project. AI Studio no muestra automáticamente todos los projects existentes; importa el correcto en Projects view antes de crear la clave.
Para el flujo actual de authorization keys en AI Studio, Google nombra:
resourcemanager.projects.get: permite verificar el project;iam.serviceAccountApiKeyBindings.create: permite vincular service account y clave.
Pide al project/organization admin un role que contenga los permisos necesarios. Google cita Project Editor como ejemplo, pero es amplio. En una organización administrada conviene el predefined/custom role mínimo aprobado, no Owner.
| Operación | Permiso o role frecuente | Qué cubre realmente |
|---|---|---|
| Crear standard Cloud API key | apikeys.keys.create en API Keys Admin (roles/serviceusage.apiKeysAdmin) | Operaciones estándar del servicio API Keys |
| Crear authorization key actual en AI Studio | resourcemanager.projects.get + iam.serviceAccountApiKeyBindings.create | Verificación de project y binding |
| Usar tuned/protected resource | Authentication específica de ruta/recurso | Uso del recurso, no creación de clave |
La referencia IAM de Google Cloud confirma apikeys.keys.create dentro de API Keys Admin. No elimina el binding step actual. Hay que alinear permission con la operación rechazada.
Un project fuera de la organización solo es válido como límite legítimo de propiedad. No debe usarse para eludir organization policy, review, quota, billing o account enforcement.
Si una clave que funcionaba empezó a devolver 403
Comprueba si la aplicación usa otra variable
Las client libraries detectan GEMINI_API_KEY y GOOGLE_API_KEY; la segunda tiene prioridad. Puede quedar una GOOGLE_API_KEY antigua, usar secret stores distintos en local/deployment, imponer una variable CI, faltar restart tras rotation o leer el framework otra provider config. Compara fingerprints y elimina el duplicate solo después de probarlo.
Cambió el contrato de unrestricted standard keys
La guía actual de Google dice que desde el 19 de junio de 2026 Gemini API empezó a rechazar requests de unrestricted standard keys. Los standard keys con restrictions explícitas pueden continuar y las claves nuevas de AI Studio son authorization keys.
No añadas una restriction arbitraria. Revisa allowed APIs, server IP/web origin real, si conviene separar un multi-API key y si migrar a authorization key es más seguro.
Un unrestricted key inactivo aparece como Blocked
La misma guía dice que desde el 7 de mayo de 2026 unrestricted keys inactivos durante un periodo prolongado pueden bloquearse y mostrar tag Blocked. La guía pública no da un número universal de días. No inventes uno.
Prueba una authorization key nueva o una restricted key existente en un entorno de bajo riesgo. Desactiva la antigua solo después de validar la sustitución.
Google detectó una clave filtrada
Google puede bloquear proactivamente known leaked keys. Crea reemplazo, actualiza secrets local/deployment, ejecuta los mismos canaries, revisa usage/billing por llamadas no autorizadas y desactiva la antigua después del éxito. Elimina la exposición de Git history, client bundles, logs, screenshots o docs. No publiques la clave comprometida.

Restricciones de API y de aplicación no son lo mismo
Una API restriction decide qué Google APIs puede llamar la clave. Para Developer API, el conjunto permitido debe coincidir con Generative Language API/Gemini route mostrado en la consola actual. Separar credentials para APIs no relacionadas mejora ownership y diagnóstico.
Una application restriction vincula uso a server IP, HTTP referrer, Android app o iOS app. Local puede funcionar y production fallar si cambió el egress IP. También puede fallar browser cuando intenta usar un server-only key. Registra el request origin real.
Una clave dentro de production browser/mobile code es un security incident distinto. Mover la llamada a backend sin rotar la clave filtrada no revoca el secreto. Sustituye, valida, desactiva la anterior y elimina la fuente.
Developer API y Vertex AI usan contratos de identidad distintos
Los canaries anteriores corresponden a generativelanguage.googleapis.com, Gemini Developer API. Vertex AI utiliza project/location resources, endpoint e identity contract diferentes. Un framework puede cambiar de route mediante base URL, provider flag o environment variable.
Si el error contiene aiplatform.googleapis.com, location, Vertex publisher model, OAuth, Application Default Credentials o service account, detén las instrucciones de Developer API key. Primero confirma Vertex identity/IAM. En sentido contrario, no añadas Vertex roles a una direct Developer API call solo por compartir el nombre Gemini.
Si solo falla un tuned model, no cambies la clave general
El ejemplo 403 de Google menciona tuned model sin authentication correcta. Identifica model owner, authorization de calling identity, resource path, project y auth method requerido. Compara con una base-model canary en la misma ruta.
Si la base model funciona y solo falla tuned model, una clave general nueva rara vez es el cambio mínimo. El resource owner debe revisar ACL o authentication.
No apliques el arreglo 403 a 400, 404, 429 o 5xx
| HTTP | Google status | Responsable habitual | Primer movimiento |
|---|---|---|---|
| 400 | INVALID_ARGUMENT | Body, field, API version | Validar request shape actual |
| 400 | FAILED_PRECONDITION | Free tier no disponible en region sin billing, entre otros | Revisar region y billing route del project |
| 403 | PERMISSION_DENIED | Wrong key, permission, protected action auth | Seguir el flujo anterior de responsable y canary |
| 404 | NOT_FOUND | Model, file, resource o version | Confirmar list y path completo |
| 429 | RESOURCE_EXHAUSTED | RPM, TPM, RPD, spend/project limit | Leer active limit del project/model |
| 500 | INTERNAL | Service failure o request issue | Revisar status y simplificar request |
| 503 | UNAVAILABLE | Capacity/outage temporal | Status y exponential backoff con jitter |
| 504 | DEADLINE_EXCEEDED | Trabajo no termina antes del deadline | Reducir carga o ajustar timeout razonable |
Si el status real es 429, consulta la guía de free tier y quota activa de Gemini API, no crees más keys. Si al recuperar permission aparece un problema de usage tier, trátalo como una rama separada de límites y elegibilidad. Credential y quota entitlement son contratos separados.
La recuperación termina cuando pasa el mismo canary en deployment
Crear una clave nueva no es el final:
- Registrar intended project, endpoint, API version, model path y credential owner.
- Ejecutar
models.listcon reemplazo o restriction corregida. - Ejecutar la misma generación mínima.
- Repetir desde deployment real.
- Confirmar monitoring, request ID y usage en el project esperado.
- Actualizar secret manager y restart/redeploy del proceso.
- Eliminar duplicate variables que ocultan la clave correcta.
- Desactivar old key después del éxito.
- Borrar temporary responses y unset de variables.
- Documentar root cause y cambio efectivo.
Rollback significa volver a la última restriction o deployment revision conocida como correcta. No significa reactivar una leaked key.
Cuándo pedir ayuda al administrador o a Google
Pide ayuda al project/organization admin si no puedes importar o inspeccionar project, falta un permiso de creación actual, organization policy bloquea uso/creación, las restrictions son centrales o project/service account/tuned model pertenece a otro equipo.
Escala a Google si el 403 sanitizado persiste con current key, correct project, endpoint y restrictions; AI Studio muestra blocked/suspicious con objetos limpios; el rechazo sigue al signed-in account; response nombra enforcement no administrable; o existe minimal reproduction y request ID sin self-service owner.
Incluye project ID, source variable y short fingerprint, endpoint/version/method/model/time, sanitized body, request ID, ambos canaries, environment/client version e historial last success/first failure. La clave completa no hace falta.
Lista de prevención
- Un credential owner claro por environment.
- Evitar competencia silenciosa entre
GOOGLE_API_KEYyGEMINI_API_KEY. - Usar current AI Studio authorization-key route cuando corresponda.
- Restringir por intended API y origin real.
- Mantener production calls detrás de backend y secret manager.
- Separar credentials para APIs y environments no relacionados.
- Monitorizar anomalías de usage/billing.
- Rotar por exposición, no por cualquier error.
- Guardar model-list/minimal-generation canary en el runbook.
- Registrar owners de project, endpoint, model y restrictions antes de launch.
Preguntas frecuentes
¿Por qué mi clave de Gemini API recibe Permission Denied?
Puede ser wrong key, una variable que oculta otra, otro project, estado Blocked/leaked, restriction que no coincide con API/origin o baseline access sin autorización para model/action. Empieza por acción rechazada y ambos canaries.
¿Debo reintentar un 403?
No. Google lo trata como client-side permission/authentication error y aconseja no reintentar 400/403. Cambia solo el responsable demostrado y repite el mismo canary.
¿Por qué AI Studio funciona pero mi código no?
Pueden diferir account, project, credential, endpoint, model o restriction. Compara selected project de AI Studio, owning project de la clave y fingerprint del deployed secret.
¿Por qué puedo listar modelos pero no generar?
La lista demuestra baseline visibility, no todas las acciones. Revisa soporte generateContent, tuned-model ownership, resource path, endpoint, project policy y body exacto.
¿Qué variable gana: GOOGLE_API_KEY o GEMINI_API_KEY?
Con ambas configuradas, la documentación actual de Google da prioridad a GOOGLE_API_KEY. Prueba el source real antes de eliminar el duplicate obsoleto.
¿Google bloqueó antiguas unrestricted keys?
La guía indica rejection de unrestricted standard keys desde el 19 de junio de 2026 y posible bloqueo de long-dormant unrestricted keys desde el 7 de mayo. Comprueba status y restrictions propios; no todas las claves antiguas son iguales.
¿Necesito API Keys Admin para crear en AI Studio?
No siempre como respuesta completa. API Keys Admin cubre standard operations como apikeys.keys.create; el current authorization-key flow nombra además resourcemanager.projects.get e iam.serviceAccountApiKeyBindings.create.
¿Activar billing corrige 403?
No de forma universal. La tabla actual de Google coloca un caso de region sin free tier y sin billing bajo 400 FAILED_PRECONDITION; 403 pertenece a permission/authentication. Lee status y message exactos.
¿Crear otro project puede arreglarlo?
Un project propio legítimo puede resolver ownership, pero no debe eludir organization policy, quota, review o account enforcement. Si clean projects repiten account-level denial, detente y escala con evidence.
Regla final de recuperación
Trata Gemini permission denied como problema de ownership, no de tiempo. Demuestra denied action, active key, project, endpoint, key state, restrictions y model auth. Haz un cambio acotado, repite los mismos canaries, verifica deployment y escala solo con evidencia sanitizada.
