「コードは何も変えていないのに、SDK をアップデートした翌日から API key not valid で落ちるようになった」— Gemini API を使い始めて最初に遭遇する地味につらい不具合のひとつです。原因の多くは API キーそのものではなく、GEMINI_API_KEY と GOOGLE_API_KEY のどちらが読まれているか、という環境変数の規約が SDK によって違う点にあります。
私自身、個人開発のアプリで Python から Node.js に書き換えた際にこの罠にハマり、2 時間ほど無駄にした経験があります。ここではSDK ごとの読み込み優先順位、Vertex AI モードに切り替わってしまう条件、ハマりやすい 4 つのパターンを、5 分で原因が特定できる切り分け手順とともに整理します。
なぜ 2 つの環境変数が併存しているのか
Gemini の SDK には世代があり、それぞれ環境変数の命名が異なります。google-generativeai(旧 SDK・2024 年前半まで主流)では明示的に genai.configure(api_key=...) で渡す前提で、環境変数の規約はありませんでした。多くの開発者が GOOGLE_API_KEY という名前を慣習的に使っていたという背景があります。
一方、現行の google-genai(新 SDK・2024 年後半〜)では公式に GEMINI_API_KEY が一次の名前として採用されました。後方互換のため GOOGLE_API_KEY も読まれますが、両方が設定されていると GEMINI_API_KEY が優先されます。さらに、GOOGLE_GENAI_USE_VERTEXAI=true を指定すると API キー方式は無効化され、Application Default Credentials(ADC)に切り替わるという、動的な分岐が入りました。
ここに LangChain や Vercel AI SDK が独自の命名(後述)を使っているため、3 つの世界観が同居している、というのが現状です。
SDK 別の優先順位早見表
主要なライブラリで、API キーがどの順序で読まれるかを整理します。
- google-genai(Python・Node.js 共通): 引数で渡した
api_key>GEMINI_API_KEY>GOOGLE_API_KEY。両方の環境変数があれば前者が勝ちます - google-genai の Vertex モード:
GOOGLE_GENAI_USE_VERTEXAI=trueが立つと API キーは無視され、GOOGLE_CLOUD_PROJECT+GOOGLE_CLOUD_LOCATION+ ADC を使った認証に切り替わります - google-generativeai(旧 Python SDK): 環境変数を自動では読まないので、
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))のように明示が必要です - LangChain
langchain-google-genai:GOOGLE_API_KEYが標準。GEMINI_API_KEYだけ設定していると読み込まれずエラーになります - Vercel AI SDK
@ai-sdk/google:GOOGLE_GENERATIVE_AI_API_KEYが標準名。これも独自規約です
つまり「同じ Gemini API キーを使っていても、ライブラリによって変数名を変えないと動かない」場合があるということです。
5 分で原因を特定する切り分けスニペット
「キーを設定したはずなのに認証エラーが出る」ときは、まず本当にどの変数がアプリプロセスから見えているかを確認します。Python なら次の 4 行を起動時に出力するだけで、原因のほぼ半分は判別できます。
import os
# どの変数が読み込まれているかを起動時に必ずログに出す
print("GEMINI_API_KEY:", "set" if os.getenv("GEMINI_API_KEY") else "missing")
print("GOOGLE_API_KEY:", "set" if os.getenv("GOOGLE_API_KEY") else "missing")
print("GOOGLE_GENAI_USE_VERTEXAI:", os.getenv("GOOGLE_GENAI_USE_VERTEXAI"))
print("GOOGLE_APPLICATION_CREDENTIALS:", os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))期待する出力例(API キー方式で正常な状態)は次のようになります。
GEMINI_API_KEY: set
GOOGLE_API_KEY: missing
GOOGLE_GENAI_USE_VERTEXAI: None
GOOGLE_APPLICATION_CREDENTIALS: None
GOOGLE_GENAI_USE_VERTEXAI: true と表示されていたら、それは Vertex モードに切り替わっているサインです。API キーは読まれず、ADC でプロジェクトに対する権限を見にいくため、ローカル開発で gcloud auth application-default login を済ませていないと 403 になります。
new SDK の Client インスタンスがどちらの経路で動いているかを確認したい場合は、次のように内部状態を覗くと一発でわかります。
from google import genai
client = genai.Client()
print("vertexai mode:", client._api_client.vertexai)
print("api_key present:", bool(client._api_client.api_key))vertexai mode: False かつ api_key present: True なら API キー経路、vertexai mode: True なら ADC 経路、と即座に判別できます。
Node.js / TypeScript で書く場合は次のように、SDK を import する前にプロセスの環境変数の状態を出力すると、サーバーレス環境でハマりやすい「ローカルでは動くのに本番で 401」を未然に防げます。
// Node.js / TypeScript: SDK 初期化前に環境変数の状態を出力する
console.log("GEMINI_API_KEY:", process.env.GEMINI_API_KEY ? "set" : "missing");
console.log("GOOGLE_API_KEY:", process.env.GOOGLE_API_KEY ? "set" : "missing");
console.log("GOOGLE_GENAI_USE_VERTEXAI:", process.env.GOOGLE_GENAI_USE_VERTEXAI ?? "unset");
console.log("GOOGLE_APPLICATION_CREDENTIALS:", process.env.GOOGLE_APPLICATION_CREDENTIALS ?? "unset");Vercel・Netlify・Cloudflare Workers では .env.local の値が自動で本番に転送されるわけではないため、上のログで missing と出ていれば「SDK のバグではなく、プラットフォーム側の環境変数設定漏れ」と即断できます。
ハマりやすい 4 つのパターンと対処
ここからは現場でよく遭遇する具体例です。
1. .env.local に GOOGLE_API_KEY を書いたのに新 SDK で 403
GOOGLE_GENAI_USE_VERTEXAI=true がどこか別のところで設定されていないか確認してください。Docker イメージや CI のシェルプロファイルに残っていることがあります。unset GOOGLE_GENAI_USE_VERTEXAI で復旧します。Vertex モードを使いたいわけでなければ、明示的に GOOGLE_GENAI_USE_VERTEXAI=false をプロジェクトに書いておくと事故を防げます。
2. dotenv が値を上書きしない
python-dotenv はデフォルトで「すでに親プロセスに変数があれば上書きしない」挙動です。古い GOOGLE_API_KEY がシェルに残ったまま新しい GEMINI_API_KEY を .env に書いても、見えるのは古い方です。load_dotenv(override=True) を指定するか、シェルセッションごと開き直すのが確実です。
3. LangChain で「Invalid API key」
LangChain は GOOGLE_API_KEY を期待します。新 SDK と同じ習慣で GEMINI_API_KEY だけにしていると無視されるので、LangChain を使うコンポーネントだけ別の変数名を要求している、と覚えておく必要があります。両方設定するか、LangChain の ChatGoogleGenerativeAI(google_api_key=os.getenv("GEMINI_API_KEY")) のように明示注入する形が安全です。
4. Cloudflare Workers / Pages でローカルでは動くのに本番で 401
Workers は .env を自動では読みません。wrangler secret put GEMINI_API_KEY でシークレットを登録するか、wrangler.toml の [vars] に書く必要があります。vars は平文でデプロイされるので、本番キーは必ず secret put 側に置いてください。
チームで運用するときの 3 つの原則
最後に、チーム開発や本番運用で事故を減らす運用ルールを 3 つ紹介します。私が個人開発で 4 サイトを運用していて、自分宛てに送り続けているメモでもあります。
①「どの認証経路で動いているか」を起動時に必ずログに出す: 上で示した 4 行を main.py の冒頭に置くだけで、本番事故の原因切り分けが格段に早くなります。本番ログに API キーの値そのものは絶対に出さないでください(set / missing だけで十分です)。
② 新規プロジェクトは GEMINI_API_KEY に統一する: 公式の優先名であり、Google Cloud の他サービス用 API キーとも見分けがつきます。既存システムで GOOGLE_API_KEY が広く使われている場合のみ既存の名前を維持し、混在は避けます。
③ CI/CD と本番で同じ変数名を使う: 環境ごとに変数名が違うと「ローカルだけ動く」現象の温床になります。CI で使う変数名は本番と完全一致させ、Vercel・Cloudflare・自前 Kubernetes など複数環境がある場合はリポジトリのルートに ENV.md を置いて一覧化しておくと、3 ヶ月後の自分が救われます。
API キーの管理方針をさらに固めたい方は、Google AI Studio で Gemini API キーを発行・管理する手順 と Gemini API 認証エラーの原因と解決法 を併読すると、設定から運用までの流れがつながります。新旧 SDK の差分そのものを把握したい方には google-genai Python SDK 完全移行ガイド も役立つはずです。
書籍で体系的に
まずは、今動いているプロジェクトの .env を開いて、GEMINI_API_KEY か GOOGLE_API_KEY のどちらを使っているかを声に出して確認するところから始めてみてください。それだけで「次に SDK を更新したときに何が起きるか」を予測できるようになります。