Gemini API 返回 403 PERMISSION_DENIED 时,先不要重试,也不要立刻换 Key。第一步是确认到底哪一步被拒绝:在 Google AI Studio 创建 Key、调用 Gemini Developer API、在 AI Studio 内生成,还是访问需要另一套认证的模型或客户端路径。先保存 HTTP 状态、原始报错、请求域名、Project、模型、时间和 request ID,但绝不能保存或发送完整 Key。
| 失败位置 | 第一个安全检查 | 先别做什么 |
|---|---|---|
| AI Studio 无法创建 Key | 确认目标 Project 已导入,并让管理员核对 resourcemanager.projects.get 与 iam.serviceAccountApiKeyBindings.create | 不要为了省事直接授予 Owner |
models.list 或所有调用都 403 | 证明当前进程实际读取哪个环境变量、Key 属于哪个 Project、API 或应用限制是否匹配 | 不要连续轮换多个 Key |
| 能列模型,生成却 403 | 核对模型路径、动作、端点、调优模型认证与 Project/账号策略 | 不要把“看得到模型”当成“有权生成” |
| AI Studio 页面提示 permission denied、blocked 或 suspicious | 核对登录账号与所选 Project,保留页面原文和时间 | 不要根据论坛案例自行判断账号被封 |
先只检查变量是否存在,不输出秘密:
bashprintf 'GOOGLE_API_KEY=%s\n' "${GOOGLE_API_KEY:+已设置}" printf 'GEMINI_API_KEY=%s\n' "${GEMINI_API_KEY:+已设置}"
如果两者都存在,Google 当前客户端文档规定 GOOGLE_API_KEY 优先。确认端点与 Project 后,再按固定顺序跑两个 canary:先列模型,再做一次最小生成。列模型已经失败,就留在凭证、Project、Key 状态、限制或端点分支;列模型成功而生成失败,再查模型、动作和认证合同。两者都成功,才去比较本地与部署配置。
当干净 canary 仍稳定失败,或者 AI Studio 在不同 Key/Project 上都给出账号级 blocked、suspicious 提示时,应停止继续创建对象。整理脱敏错误、Project ID、Key 指纹、端点、模型、时间、request ID 与 canary 结果,交给 Project 管理员或 Google 支持。
403 的重点不是“Key 对不对”,而是谁拒绝了哪个动作
API Key 是绑定 Google Cloud Project 的凭证,但它本身不是 IAM 策略、计费账户、配额桶、模型授权、端点,也不是当前登录的 AI Studio 账号。因此,即使 Key 格式正确、能在某个页面看见,也不能证明每个动作都有权限。
Google 当前的 Gemini API 问题排查指南 将 403 PERMISSION_DENIED 归为 Key 缺少所需权限,并举出错误 Key、调优模型认证不正确等情况。该指南也明确建议不要重试 400 和 403 这类客户端错误。等待只会改变时间,不会替你更换错误凭证、修正限制或获得资源授权。
中文结果页常把“未启用 API”“没有计费”“Vertex AI User”“地区不可用”“请求过快”一起塞进 403 清单。这些都可能对应某个真实案例,却不是同一个合同。正确问题不是“十个方法应该从哪个开始试”,而是“哪个动作失败,这个动作由谁管理”。

| 被拒动作 | 主要责任方 | 能缩小范围的证据 | 最小下一步 |
|---|---|---|---|
| 在 AI Studio 创建 Key | Project 导入、IAM、组织策略、服务账号绑定 | 页面原文、Project ID、登录账号、缺少的 permission | 向管理员申请最窄权限,或使用自己合法拥有的 Project |
| 列出模型 | 生效 Key、归属 Project、API/应用限制、端点 | 变量来源、Key 指纹、域名、HTTP 状态、脱敏 body | 只改一个不匹配项,然后重跑列表 canary |
| 生成内容 | 模型/动作授权、调优模型认证、Project/账号策略 | 列表结果、模型路径、生成状态、request ID | 同一路径测试一个当前基础模型,保留动作级错误 |
| 在 AI Studio 内生成 | 登录账号、选中 Project、AI Studio 执行策略 | 页面提示、Project 选择、时间、请求证据 | 在归属清楚前不要继续切 Project 或 Key |
| 本地成功、服务器失败 | 部署 secret、变量优先级、IP/来源限制、旧版本 | 本地和部署指纹、revision、出口 IP/来源 | 只更新实际失配的 secret 或限制,再测那次部署 |
改配置之前,先留下一份不泄密的错误证据
第一次失败往往最干净。轮换 Key、改 restriction、换 Project 或重新部署,会把“原本为什么失败”埋掉。至少记录:
- UTC 时间与本地时区;
- HTTP 状态、状态名、完整但已脱敏的错误 body;
- endpoint hostname、API version、HTTP method;
- 模型或资源路径;
- 所选或配置的 Project ID;
- SDK/客户端版本;
- response 中的 request ID、trace ID 或 correlation ID;
- 发生在 AI Studio、本地、CI 还是生产;
models.list和最小generateContent是否表现不同。
不要记录完整 API Key、带 Key 的截图、整份环境变量、cookie、OAuth token、服务账号 JSON、无关 secret,或包含用户隐私的生产 prompt。
需要比较本地、CI 和生产是否使用同一凭证时,可以生成单向短指纹:
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 环境变量" exit 1 fi printf 'source=%s length=%s sha256=' "$KEY_SOURCE" "${#ACTIVE_KEY}" printf '%s' "$ACTIVE_KEY" | shasum -a 256 | cut -c1-12
12 位 hash 前缀不是 Key,适合用来判断两个环境读到的是相同还是不同 secret。但它仍是内部事件证据,不要公开贴到搜索引擎、论坛或 issue。
用两次请求把“基础访问”和“动作权限”拆开
Canary 的价值来自控制变量:端点、Project 和凭证保持不变,每次只改一个已被证据指向的设置,再重复同一组请求。

Canary 1:列出模型
Gemini Developer API 使用 generativelanguage.googleapis.com。下面的命令通过 header 文件描述符传递 Key,避免把秘密直接写进命令参数,同时把返回 body 留在本机临时文件:
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
- 列模型就 403:继续检查当前 Key、归属 Project、Key 状态、API restriction、application restriction 与端点。
- 返回 200 和模型列表:只证明基础访问存在,不代表每个模型与动作都获准。
- 返回 404 或响应结构异常:先核对 hostname、API version、代理 base URL 与请求构造。
- 返回 429:权限分支已经改变,应转去查配额和速率,而不是继续修 403。
Canary 2:最小生成
从列表响应中选择一个当前明确支持 generateContent 的模型路径,不要从旧文章复制可能已下线的 model ID。测试前也应确认当前价格和资格,因为 canary 仍是一笔真实调用。
bashMODEL_PATH='models/<从列表复制当前支持-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":"只回复 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
| 列模型 | 生成 | 判断 |
|---|---|---|
| 403 | 不再生成 | 拒绝发生在动作之前:生效 Key、Project、Key 状态、restriction 或端点 |
| 200 | 403 | 基础访问成立;检查模型/动作授权、调优模型认证、Project 或账号策略与原始 body |
| 200 | 404 | 模型路径、API version 或该路线的模型可用性不匹配 |
| 200 | 429 | 权限已成立,接下来由 quota、tier 或流量形状负责 |
| 200 | 200 | 基础路线正常;比较应用代码、部署 secret、headers、代理、地区与配置 |
记录脱敏结果后清理临时数据:
bashrm -f /tmp/gemini-models.json /tmp/gemini-generate.json unset ACTIVE_KEY
AI Studio 提示“无权在此 Project 创建 Key”怎么处理
这个错误发生在应用拿到可用 Key 之前。改 generateContent、模型名或重试逻辑不会解决它。
Google 当前的 Gemini API Key 指南 说明,每个 Key 都属于一个 Google Cloud Project。AI Studio 不会自动展示你能看到的所有现有 Project;先在 Projects 视图中导入正确 Project,再进行创建。
对当前 AI Studio authorization key 流程,Google 明确列出:
resourcemanager.projects.get:让 AI Studio 验证 Project;iam.serviceAccountApiKeyBindings.create:把服务账号与 Key 绑定。
应让 Project 或组织管理员提供包含这些 permission 的最窄可用角色。Google 会把 Project Editor 作为示例,但 Editor 覆盖范围很大;受管理组织更适合使用已经审批的预定义角色或 custom role,而不是直接给 Owner。
容易混淆的地方是,旧答案常只说 API Keys Admin:
| 操作 | 常见 permission/role | 实际覆盖范围 |
|---|---|---|
| 创建标准 Cloud API Key | apikeys.keys.create,包含于 API Keys Admin(roles/serviceusage.apiKeysAdmin) | API Keys 服务的标准操作 |
| 创建当前 AI Studio authorization key | resourcemanager.projects.get + iam.serviceAccountApiKeyBindings.create | Project 验证与服务账号-Key 绑定 |
| 调用调优模型或受保护动作 | 路线/资源指定的认证 | 使用受保护资源,不是创建 Key |
Google Cloud IAM permission 参考 能证明 apikeys.keys.create 属于 API Keys Admin,却不能替代当前 authorization-key 的绑定步骤。必须把 permission 对准失败动作。
没有管理权限时,Google 指南允许考虑在组织外创建自己拥有的新 Cloud Project。但这只适用于合法的所有权边界,不能用来绕过组织政策、审核、计费、配额或账号执法。
Key 之前能用、现在突然 403,要按四个方向查
“以前成功”只能证明过去某个时刻的某个请求成立,不能证明当前进程仍用同一 Key,也不能证明旧 Key 仍符合 2026 年规则。
1. 实际读取了另一个环境变量
客户端会自动识别 GEMINI_API_KEY 和 GOOGLE_API_KEY;两者并存时后者优先。常见现场包括:旧的 GOOGLE_API_KEY 遮住刚轮换的 GEMINI_API_KEY、本地与部署使用不同 secret manager、CI 变量覆盖项目级 secret、进程轮换后没有重启、框架读取自己的 provider 配置。先比较指纹,再删除已确认过期的重复变量。
2. 不受限的标准 Key 已不符合 Gemini 路线要求
Google 当前 Key 指南写明:从 2026 年 6 月 19 日起,Gemini API 开始拒绝不受限的 standard key;带明确 restriction 的 standard key 可以继续使用,AI Studio 新创建的 Key 则都是 authorization key。
这不意味着随便加一个 restriction 就结束。要确认允许的 API 是否包含实际 Gemini 路线,application restriction 是否匹配当前服务器 IP、网站来源、Android 或 iOS 应用,共用多 API 的 Key 是否应该拆分,以及新建 authorization key 是否比维护旧 standard key 更安全。
3. 长期未使用的不受限 Key 被标记 Blocked
同一份指南说明,从 2026 年 5 月 7 日起,长期休眠的不受限 Key 可能被阻断,并在 AI Studio 显示 Blocked。公开文档没有给所有账号通用的休眠天数,因此不要凭空写“90 天”或其他阈值。
应改用新的 authorization key 或现有受限 Key,先在低风险环境验证,通过后再停用旧凭证。
4. Key 被判定泄露
Google 排错指南说明,已知泄露的 Key 可能被主动阻断。此时应新建替代 Key、更新本地与部署 secret、跑同一组 canary、查看近期 usage/billing 是否有异常、确认替代路线通过后禁用旧 Key,并从 Git 历史、客户端 bundle、日志、截图或文档中清除泄露来源。不要把已泄露 Key 贴进论坛或普通支持表单。

API restriction 与 application restriction 要分别核对
Restriction 本来就是权限边界;请求不满足边界时,403 可能正是预期行为。
API restriction
它限定 Key 可以调用哪些 Google API。对 Gemini Developer API,要确认当前控制台里允许的 API 与 Generative Language API/Gemini 路线匹配。生产环境不要让一个 Key 同时承担许多无关 Google API,否则出错时很难判断责任方。
Application restriction
它把调用绑定到服务器 IP、HTTP referrer、Android 应用或 iOS 应用。本地成功、生产失败,常见原因是生产出口 IP 改了;生产成功、浏览器失败,也可能是 server-only Key 被拿到前端使用。记录真实请求来源,不要只相信架构图上“应该”的来源。
前端暴露不是普通 403,而是安全事件
不要把 Gemini API Key 写进生产浏览器或移动端包。Google 推荐通过后端代理调用,因为 bundle 可以被检查。若 Key 已经出现在客户端,把调用搬到后端但不轮换旧 Key,泄露仍然存在。正确顺序是先限制影响、创建替代凭证、更新服务、验证、停用旧 Key,再清除暴露源并检查异常使用。
Gemini Developer API 与 Vertex AI 不能混用一套排错法
generativelanguage.googleapis.com 是本文 canary 对应的 Gemini Developer API。Vertex AI 使用 Google Cloud Project/location 资源、不同 endpoint 和身份合同。框架可能通过 base URL、provider flag 或环境变量悄悄切换路线。
如果错误里出现 aiplatform.googleapis.com、location、Vertex publisher model、OAuth、Application Default Credentials 或 service account,就应停止套用 Developer API Key 指令,先确认 Vertex 路线的身份与 IAM。反过来,直接调用 Developer API 时也不要因为都叫 Gemini 就添加 Vertex 角色。
只有调优模型失败时,别再换通用 Key
Google 的 403 示例特别提到调优模型认证不正确。应确认调优模型归属、调用身份是否获权、资源路径与 Project 是否一致、该路线要求哪种认证,并用同路线的基础模型做对照。
基础模型成功、只有 tuned model 失败,说明普通 Key 至少已通过基础访问。继续轮换通用 Key 通常不是最小修复,应由调优资源所有者处理 ACL 或认证。
别把 400、404、429 与 5xx 当成同一个 403
| HTTP | Google 状态 | 常见责任方 | 第一动作 |
|---|---|---|---|
| 400 | INVALID_ARGUMENT | body 字段、API version、请求结构 | 按当前 reference 校验参数 |
| 400 | FAILED_PRECONDITION | 某些地区无免费层且未启用 billing | 查当前地区资格与 Project billing 路线 |
| 403 | PERMISSION_DENIED | Key 权限、错误 Key、受保护模型/动作认证 | 走本文 owner 与 canary 流程 |
| 404 | NOT_FOUND | 模型、文件、资源或版本不匹配 | 查当前模型列表与完整资源路径 |
| 429 | RESOURCE_EXHAUSTED | RPM、TPM、RPD、消费或 Project 限额 | 读取当前 Project/模型限制 |
| 500 | INTERNAL | 服务端异常或过大 context 等情况 | 查状态页并缩小请求,再有限重试 |
| 503 | UNAVAILABLE | 临时容量或服务不可用 | 查状态并使用带 jitter 的指数退避 |
| 504 | DEADLINE_EXCEEDED | 请求未在 deadline 内完成 | 减少工作量或合理调整 timeout |
真实错误是 429 时,去看 Gemini API 免费层与实时配额指南,不要继续创建 Key。权限恢复后如果暴露的是 usage tier 问题,再看 Gemini API Tier 3 指南。凭证与配额 entitlement 不是一个合同。
修复后必须在真实部署环境闭环
新 Key 能创建出来,不代表事故结束。完成标准应是:同一组受控测试在目标环境通过,旧状态可以安全退出。
- 记录目标 Project、endpoint、API version、模型路径与凭证负责人。
- 用替代 Key 或修复后的 restriction 运行
models.list。 - 运行相同的最小生成请求。
- 在实际部署环境重复测试。
- 确认监控、request ID 与 usage 出现在预期 Project。
- 更新 secret manager,并重启或重新部署读取 secret 的进程。
- 删除会遮蔽正确 Key 的重复变量。
- 替代凭证通过后再禁用旧 Key。
- 删除临时响应文件并 unset shell 变量。
- 记录根因和唯一有效修复。
Rollback 是恢复最后一个确认正常的 restriction 或 deployment revision,不是重新启用泄露 Key。
什么时候找管理员,什么时候找 Google
无法导入/查看 Project、缺少当前 Key 创建 permission、组织政策禁止创建或使用 Key、restriction 由中央管理,或 Project/服务账号/调优模型属于别的团队时,先找 Project 或组织管理员。
当前 Key、正确 Project、正确 endpoint、有效 restriction 下仍稳定 403;AI Studio 在干净 Key/Project 上仍报告 blocked 或 suspicious;拒绝跟随登录账号;错误明确指向不可管理的 Project enforcement;或已有最小复现与 request ID 却不存在自助责任方时,再通过 AI Studio feedback 或对应 Google Cloud support 路线升级。
支持材料应只包含:Project ID、Key 来源变量和短指纹、endpoint/API version/method/model/time、脱敏错误、request ID、两个 canary 结果、环境与客户端版本、最后成功/首次失败时间及轮换/restriction 变化。不要提交完整 Key。
预防下一次 403 的运行清单
- 每个环境只保留一个明确凭证负责人。
- 避免
GOOGLE_API_KEY与GEMINI_API_KEY无意竞争。 - 适合时使用当前 AI Studio authorization-key 路线。
- 同时配置目标 API 与真实调用来源的最小 restriction。
- 生产调用放在后端,Key 存 secret manager。
- 无关 API 和环境使用不同凭证。
- 监控 usage 与 billing 中的异常调用。
- 泄露时轮换,不要对所有错误都轮换。
- 在 runbook 保留模型列表与最小生成 canary。
- 上线前记录 Project、endpoint、model 与 restriction 负责人。
- 事故处理中复核 Google 的日期化 Key 规则。
常见问题
Gemini API Key 为什么会权限被拒绝?
可能是错误或被其他变量遮蔽的 Key、不同 Project、Blocked/泄露状态、API/来源 restriction 不匹配,或只具备基础访问却无权调用目标模型/动作。先按失败位置分类,再跑两个 canary,不要默认就是 IAM。
403 应该多重试几次吗?
不应该。Google 当前排错说明把 403 视为客户端权限或认证错误,并建议不要重试 400/403。只修改被证据证明的责任方,然后重复同一 canary。
为什么 AI Studio 能用,代码调用却失败?
AI Studio 与应用可能使用不同登录账号、Project、凭证、endpoint、模型或 restriction。比较 AI Studio 选中的 Project、Key 归属 Project 与部署 secret 指纹。
为什么能列出模型,却不能生成?
列模型只证明基础可见性,不代表每个 action 都获权。应检查目标模型是否支持 generateContent、调优模型归属、资源路径、endpoint、Project 策略与原始 403。
GOOGLE_API_KEY 和 GEMINI_API_KEY 哪个生效?
Google 当前客户端文档规定两者同时设置时 GOOGLE_API_KEY 优先。先证明进程读取哪个变量,再处理陈旧重复项。
Google 是否阻断了旧的不受限 Key?
Google 指南写明,Gemini API 从 2026 年 6 月 19 日起拒绝不受限 standard key,并从 2026 年 5 月 7 日起可能阻断长期休眠的不受限 Key。应查看 AI Studio 的真实状态与 restriction,不能推断所有旧 Key 都已失效。
在 AI Studio 创建 Key 一定需要 API Keys Admin 吗?
不一定是完整答案。API Keys Admin 覆盖 apikeys.keys.create 等标准 API Keys 操作;当前 AI Studio authorization-key 流程另列 resourcemanager.projects.get 与 iam.serviceAccountApiKeyBindings.create。应按失败动作申请最窄 permission。
开通计费能修复 403 吗?
不能一概而论。Google 当前错误表把某些“地区不支持免费层且未启用 billing”的情况归为 400 FAILED_PRECONDITION,而 403 属于权限/认证。先看准确 status 与 message,再决定是否处理 billing。
新建 Project 能解决吗?
自己合法拥有的新 Project 可以解决 Project 管理边界,但不能用于绕过组织政策、配额、审核或账号 enforcement。干净 Project 仍复现账号级错误时,应停止创建并携证据升级。
最终恢复原则
把 Gemini permission denied 当作责任归属问题,而不是等待问题。确认失败动作、生效 Key、归属 Project、endpoint、Key 状态、restriction 和模型认证;每次只改一个被证据指向的设置,重复同一 canary,在部署环境验证,再以脱敏证据升级。
