Gemini APIが403 PERMISSION_DENIEDを返したら、最初に課金設定を変えたり、新しいAPIキーを何本も作ったりしないでください。まず、拒否された処理を一つに特定します。Google AI Studioでキーを作る処理、Gemini Developer APIの呼び出し、AI Studio内の生成、または別の認証方式を必要とするmodel/client routeのどれでしょうか。HTTP status、エラー本文、endpointのhostname、選択中のproject、model、時刻、request IDを保存します。ただし完全なキーは保存・共有しません。
| 失敗した場所 | 最初の安全な確認 | 先に行わないこと |
|---|---|---|
| AI Studioでキーを作れない | 対象projectがimport済みか確認し、管理者にresourcemanager.projects.getとiam.serviceAccountApiKeyBindings.createを確認してもらう | Ownerを安易に付与しない |
models.listを含む全呼び出しが403 | 実際に読み込まれた環境変数、キーの所属project、API/application restrictionを確認する | 複数のキーを連続でrotateしない |
| モデル一覧は取れるが生成だけ403 | model path、action、endpoint、tuned modelの認証、project/account policyを確認する | 一覧に見えることを生成権限とみなさない |
| AI Studio自体がblocked、suspicious、permission deniedを表示 | signed-in accountと選択projectを確認し、表示原文と時刻を残す | 他人のforum事例だけでaccount停止と断定しない |
キーを表示せず、変数が存在するかだけを確認します。
bashprintf 'GOOGLE_API_KEY=%s\n' "${GOOGLE_API_KEY:+set}" printf 'GEMINI_API_KEY=%s\n' "${GEMINI_API_KEY:+set}"
両方が設定されている場合、Googleの現在のclient library docsではGOOGLE_API_KEYが優先されます。endpointとprojectを確認したら、同じcredentialで「モデル一覧」「最小生成」の順に二つのcanaryを実行します。一覧が失敗するならキー、project、キー状態、restriction、endpointを調べます。一覧は成功し生成だけ失敗するならmodel/action/authenticationに移ります。両方成功したときだけlocalとdeploymentの設定差を調べます。
正しい設定でcanaryが繰り返し失敗する、またはAI Studioが複数の正常なキー/projectでaccount-levelのblockedやsuspiciousを示すなら、オブジェクトを増やすのを止めます。sanitized error、project ID、キーの短いfingerprint、endpoint、model、timestamp、request ID、canary結果を管理者またはGoogle supportに渡します。
403は「キーがあるか」ではなく「どの処理を誰が拒否したか」で読む
APIキーはGoogle Cloud projectに紐づくcredentialです。IAM policy、billing account、quota bucket、model permission、endpoint、AI Studioのsigned-in accountそのものではありません。そのため、キーの形式が正しいことや、昨日まで動いたことだけでは、今日のactionが許可されている証明になりません。
現在のGemini APIトラブルシューティング ガイドは、403 PERMISSION_DENIEDを必要な権限を持たないキーのエラーとして説明しています。wrong keyと、正しいauthenticationなしでtuned modelを使う例も挙げています。また400と403のようなclient errorはretryしないよう案内しています。時間を置くだけでは、誤ったcredential、restriction、resource authorizationは変わりません。
日本語のGoogle画面では、AI概要が課金、APIキー制限、廃止対応をまとめて提示し、自然結果には「突然の403」、AI Studio、403/429の総合解説、IAM不足が並びます。これらは候補を知るには役立ちますが、同じ修正を当てる理由にはなりません。403の前に400 FAILED_PRECONDITIONや429を混ぜると、無関係なbillingやquotaを先に変更してしまいます。

| 拒否された処理 | 主な管理先 | 範囲を絞る証拠 | 最小の次手 |
|---|---|---|---|
| AI Studioでキー作成 | Project import、IAM、organization policy、service-account binding | UI原文、project ID、account、missing permission | 管理者に最小権限を依頼するか、自分が正当に所有するprojectを使う |
| モデル一覧取得 | Active key、owning project、API/application restriction、endpoint | 変数名、fingerprint、hostname、status、sanitized body | 不一致を一つだけ直し、list canaryを再実行 |
| コンテンツ生成 | Model/action authorization、tuned-model auth、project/account policy | list結果、model path、generation status、request ID | 同じrouteのcurrent base modelと比較 |
| AI Studio内で生成 | Signed-in account、選択project、AI Studio enforcement | UI message、project、時刻 | 所有者が分かるまでproject/keyを切り替えない |
| Localだけ成功 | Deployed secret、env precedence、IP/origin restriction、古いrevision | local/deploy fingerprint、revision、egress IP/origin | ずれたsecretまたはrestrictionだけを修正 |
設定を変える前に、秘密を含まないエラー記録を作る
最初のfailed requestは、原因を示す最もきれいな証拠になりやすいものです。rotation、restriction編集、project変更、redeployの前に次を記録します。
- UTC timestampとlocal timezone
- HTTP status、status name、sanitized response body
- endpoint hostname、API version、method
- modelまたはresource path
- project ID
- SDK/client version
- responseに含まれるrequest ID、trace ID、correlation ID
- AI Studio、local、CI、productionのどこで失敗したか
models.listと最小generateContentの結果差
完全なAPIキー、キーが写ったscreenshot、全environment dump、cookie、OAuth token、service-account JSON、無関係なsecret、個人情報を含むproduction promptは含めません。
環境ごとのcredentialを比較する場合は、一方向の短いfingerprintを使えます。
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
12文字のhash prefixはキーではありません。同じsecretか別のsecretかを判断するための内部証拠です。fingerprintもpublic issueには貼らず、社内incidentか安全なsupport channelで扱います。
二つのcanaryでbaseline accessとmodel actionを分ける
Canaryではcredential、project、endpointを固定します。証拠で特定した設定を一つだけ変え、同じ二つのrequestで差を確認します。

Canary 1:モデル一覧
Gemini Developer APIのhostnameはgenerativelanguage.googleapis.comです。次の例はkeyをtyped command lineに直接含めず、response bodyをlocal temporary fileに保存します。
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:active key、project、key state、restriction、endpointの枝に残る。
- 200とmodel list:baseline accessは成立。ただし全model/actionの許可ではない。
- 404または想定外のbody:hostname、API version、proxy/base URL、request constructionを先に直す。
- 429:permissionではなくquota/rate-limitの枝に移る。
Canary 2:最小生成
List responseから、現在generateContentをsupportするmodel pathを選びます。古い記事からmodel IDをコピーしないでください。Canaryも実際のcallなので、current pricingとeligibilityも確認します。
bashMODEL_PATH='models/<listで確認したgenerateContent対応model>' 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
| Model list | Generate | 判断 |
|---|---|---|
| 403 | 実行しない | Model actionより前で拒否。key、project、key state、restriction、endpoint |
| 200 | 403 | Baselineは成功。model/action auth、tuned resource、project/account policy |
| 200 | 404 | Model path、API version、route上のavailabilityが不一致 |
| 200 | 429 | Permissionは成功。quota、tier、traffic shapeを確認 |
| 200 | 200 | 基本routeは正常。app code、deployed secret、headers、proxy、regionを比較 |
Sanitized resultsを記録したらtemporary fileとshell variableを消します。
bashrm -f /tmp/gemini-models.json /tmp/gemini-generate.json unset ACTIVE_KEY
AI Studioで「このprojectにキーを作る権限がない」と出る場合
これはapplication callより前の拒否です。generateContent、model名、retry設定を変えても直りません。
現在のGemini APIキー ガイドは、すべてのキーがGoogle Cloud projectに所属すると説明しています。AI Studioは既存projectをすべて自動表示しないため、Projects viewで対象projectをimportしてから作成します。
現在のAI Studio authorization-key flowでGoogleが示すpermissionは次の二つです。
resourcemanager.projects.get:AI Studioがprojectを確認するためiam.serviceAccountApiKeyBindings.create:service accountをkeyにbindするため
Project/organization adminには、その処理を満たす最小のroleを依頼します。GoogleはProject Editorを例示しますが、Editorは広い権限です。管理組織では承認済みpredefined roleまたはcustom roleを選び、Ownerを安易に付けません。
| キー操作 | よく挙げられるpermission/role | 実際の範囲 |
|---|---|---|
| Standard Cloud API keyを作る | apikeys.keys.createを含むAPI Keys Admin(roles/serviceusage.apiKeysAdmin) | API Keys serviceの標準操作 |
| Current AI Studio authorization keyを作る | resourcemanager.projects.getとiam.serviceAccountApiKeyBindings.create | Project確認とservice-account binding |
| Tuned/protected resourceを使う | Route/resource固有のauthentication | Key作成ではなくresource利用 |
Google Cloud IAM permission referenceでapikeys.keys.createがAPI Keys Adminに含まれることは確認できます。しかし現在のbinding stepを置き換える情報ではありません。拒否されたoperationにpermissionを合わせます。
管理権限がないとき、自分が正当に所有できるorganization外projectを使う選択肢はあります。ただしorganization policy、review、quota、billing、account enforcementを回避するために作ってはいけません。
昨日まで動いたキーが突然403になった場合
実際には別のキーが読まれていないか
Client librariesはGEMINI_API_KEYとGOOGLE_API_KEYを自動検出し、両方あれば後者を優先します。古いGOOGLE_API_KEYが新しい値を隠す、localとdeploymentが別のsecret managerを使う、CI variableがproject secretをoverrideする、rotation後にprocessをrestartしていない、frameworkが独自credential fieldを読む、といったケースがあります。Fingerprintで証明してからobsolete duplicateを削除します。
Unrestricted standard keyの扱いが変わった
現在のGoogle guideでは、2026年6月19日からGemini APIがunrestricted standard keyのrequestを拒否し始めたと説明しています。明示的なrestrictionを持つstandard keyは継続可能で、AI Studioで新規作成されるkeyはauthorization keyです。
適当なrestrictionを一つ追加するのではなく、allowed API、実際のserver IPやweb origin、multi-API keyを分割すべきか、新しいauthorization keyへ移す方が安全かを確認します。
Dormantなunrestricted keyがBlockedになった
同じguideは、2026年5月7日以降、長期間使われていないunrestricted keyがblockされ、AI StudioでBlocked tagを表示する場合があると説明しています。公開guideに全account共通のinactive日数はありません。根拠のない日数を判断条件にしないでください。
新しいauthorization keyまたは既存restricted keyをlow-risk environmentで確認し、replacementが通ってから古いcredentialを無効化します。
Leaked keyとしてblockされた
Googleは既知のleaked keyをproactiveにblockする場合があります。Replacementを作り、local/deployed secretを更新し、同じcanaryを実行し、usage/billingに不正callがないか確認します。成功後に古いkeyを無効化し、Git history、client bundle、logs、screenshots、docsから漏えい元を除去します。Full keyをforumやsupport formに貼る必要はありません。

API restrictionとapplication restrictionは別々に確認する
API restrictionは、keyが呼べるGoogle APIを限定します。Gemini Developer APIでは、current consoleに表示されるGenerative Language API/Gemini routeとallowed APIが一致する必要があります。無関係な複数APIを一つのproduction keyで使うとownershipが不明瞭になります。
Application restrictionはserver IP、HTTP referrer、Android app、iOS appに使用元を限定します。Localは成功しproductionだけ失敗するなら、egress IPが変わった可能性があります。Server-only keyをbrowserから使えば逆の失敗も起きます。想定ではなく実際のrequest originを記録します。
Production browser/mobile codeにGemini keyを埋め込むことは、通常の403とは別のsecurity incidentです。Backend proxyへ移すだけでは、すでに漏れたkeyは生きたままです。Replacement、service更新、検証、old key停止、漏えい元の除去まで行います。
Gemini Developer APIとVertex AIを混同しない
上のcanaryはgenerativelanguage.googleapis.comを使うGemini Developer API向けです。Vertex AIはGoogle Cloud project/location resource、別endpoint、別identity contractを使います。Frameworkがbase URL、provider flag、environment variableによってrouteを切り替えることもあります。
Errorにaiplatform.googleapis.com、location、Vertex publisher model、OAuth、Application Default Credentials、service accountが含まれるなら、Developer API keyの手順を止めます。先にVertexのidentity/IAMを確認します。直接Developer APIを呼んでいる場合に、同じGeminiという名前だけでVertex roleを追加するのも誤りです。
Tuned modelだけ失敗するなら一般キーを増やさない
Googleの403 exampleは、正しいauthenticationなしでtuned modelを使うケースを挙げます。Model owner、calling identityのauthorization、resource path、project、必要なauth methodを確認し、同じrouteでbase-model canaryと比較します。
Base modelが成功しtuned modelだけ失敗するなら、一般APIキーの交換は最小修正ではありません。Protected resourceのACLまたはauthenticationをresource ownerが直すべきです。
400、404、429、5xxには別の修復を使う
| HTTP | Google status | 主な管理先 | 最初の処理 |
|---|---|---|---|
| 400 | INVALID_ARGUMENT | Body field、API version、request shape | Current referenceと比較 |
| 400 | FAILED_PRECONDITION | Free tier非対応regionでbillingなし等 | Region eligibilityとproject billing routeを確認 |
| 403 | PERMISSION_DENIED | Wrong key、permission、protected action auth | 本文のowner/canary手順 |
| 404 | NOT_FOUND | Model、file、resource、version | Current model listとfull pathを確認 |
| 429 | RESOURCE_EXHAUSTED | RPM、TPM、RPD、spend/project limit | Active project/model limitを読む |
| 500 | INTERNAL | Service-side failureまたはrequest issue | Status確認、request縮小、限定retry |
| 503 | UNAVAILABLE | Temporary capacity/outage | Status確認とjitter付きexponential backoff |
| 504 | DEADLINE_EXCEEDED | Deadlineまでに完了しない | Work削減または妥当なtimeout調整 |
実際のstatusが429なら、キーを増やさずGemini API無料枠と現在のquotaガイドに移ります。Permission回復後にusage tierが問題だと分かったらGemini API Tier 3ガイドを確認します。Credentialとquota entitlementは別契約です。
修復はdeploymentで同じcanaryが通って完了する
新しいキーを作れただけでは完了ではありません。
- Intended project、endpoint、API version、model path、credential ownerを記録。
- Replacementまたは修正後restrictionで
models.listを実行。 - 同じ最小生成を実行。
- 実際のdeploymentから再実行。
- Monitoring、request ID、usageが期待するprojectに属するか確認。
- Secret managerを更新し、consumer processをrestart/redeploy。
- 正しいkeyを隠すduplicate variableを削除。
- Replacement成功後にold keyをdisable。
- Temporary responseとshell variableを削除。
- Root causeと有効だった変更を記録。
Rollbackは最後に確認済みのrestrictionまたはdeployment revisionへ戻すことです。Leaked keyを再有効化することではありません。
管理者またはGoogleへ渡す境界
Projectをimport/inspectできない、current create-key permissionがない、organization policyがkey creation/useを止める、restrictionが中央管理、project/service account/tuned modelが別team所有なら、project/organization adminへ依頼します。
Current key、correct project、endpoint、valid restrictionsでもsanitized 403が続く、AI Studioがclean keys/projectsでblocked/suspiciousを示す、拒否がsigned-in accountを追従する、responseが管理不能なenforcementを示す、またはminimal reproductionとrequest IDがあるのにself-service ownerが残らない場合はGoogleへエスカレーションします。
渡すのはproject ID、source variableとshort fingerprint、endpoint/version/method/model/time、sanitized body、request ID、二つのcanary、environment/client version、last success/first failureと変更履歴です。完全なkeyは不要です。
再発防止チェック
- Environmentごとにcredential ownerを一人にする。
GOOGLE_API_KEYとGEMINI_API_KEYを競合させない。- 適切な場合はcurrent AI Studio authorization-key routeを使う。
- Intended APIと実際のoriginに最小restrictionを設定する。
- Production callはbackend経由、keyはsecret managerへ置く。
- 無関係なAPI/environmentでcredentialsを分ける。
- Usage/billing anomalyをmonitorする。
- Exposure時はrotateするが、無関係なerrorでrotateしない。
- Model-list/minimal-generation canaryをrunbookへ置く。
- Launch前にproject、endpoint、model、restriction ownerを記録する。
よくある質問
Gemini APIキーが403になる主な理由は何ですか?
Wrong key、別env variableによるshadow、違うproject、Blocked/leaked state、API/origin restrictionの不一致、またはbaseline accessはあるが対象model/actionの権限がない状態が考えられます。失敗処理と二つのcanaryから始めます。
403は何回か再試行すれば直りますか?
いいえ。Googleは403をclient-side permission/authentication errorとして扱い、400/403をretryしないよう案内します。証拠で示された管理先だけを変えて同じcanaryを再実行します。
AI Studioでは使えるのにコードでは失敗するのはなぜですか?
Account、project、credential、endpoint、model、restrictionが異なる可能性があります。AI Studioのselected project、key owning project、deployed secret fingerprintを比較します。
モデル一覧が成功し生成だけ拒否されるのはなぜですか?
一覧はbaseline visibilityしか証明しません。generateContent support、tuned model ownership、resource path、endpoint、project policy、403 bodyを確認します。
GOOGLE_API_KEYとGEMINI_API_KEYはどちらが優先ですか?
現在のGoogle docsでは両方が設定されるとGOOGLE_API_KEYが優先されます。実際のsourceを特定してからobsolete duplicateを削除します。
Googleは古いunrestricted keyを止めましたか?
Guideは2026年6月19日からunrestricted standard keyを拒否し、2026年5月7日からlong-dormant unrestricted keyをblockする場合があると説明します。自分のkey statusとrestrictionを確認し、全old keyが同じとは判断しません。
AI Studioのキー作成にはAPI Keys Adminが必要ですか?
それだけが完全な答えではありません。API Keys Adminはapikeys.keys.createなどstandard operationを含みますが、current authorization-key flowはresourcemanager.projects.getとiam.serviceAccountApiKeyBindings.createを別に示します。
課金を有効にすれば403は直りますか?
一律には直りません。Googleのcurrent error tableでは、free tier非対応regionでbillingなしという一例は400 FAILED_PRECONDITIONで、403はpermission/authenticationです。正確なstatus/messageを先に読みます。
新しいprojectを作れば解決しますか?
自分が正当に所有するprojectはownership boundaryを解決できますが、organization policy、quota、review、account enforcementの回避には使えません。Clean projectでもaccount-level denialが続くなら作成を止め、evidenceを付けてエスカレーションします。
復旧の最終ルール
Gemini permission deniedは時間ではなくownershipの問題として扱います。Denied action、active key、project、endpoint、key state、restrictions、model authを証明し、一度に一つだけ変更します。同じcanaryを繰り返し、deploymentで確認し、必要なときだけsanitized evidenceでエスカレーションしてください。
