← 목록

"Invalid API key" or undefined env vars on Vercel: how to fix it

devto 2026-10-19 원문 보기 ↗


Your app works on your machine. You deploy to Vercel and get one of these:

Error: supabaseUrl is required.
AuthApiError: Invalid API key
OpenAI API error: 401 Incorrect API key provided: undefined

Or process.env.MY_KEY is simply undefined in production.

Why it happens

Fix 1: add the variables in Vercel, then redeploy

Vercel → Project → Settings → Environment Variables. Add each key, tick the environments that need it, then redeploy (Deployments → ⋯ → Redeploy). Or use the CLI:

vercel env add NEXT_PUBLIC_SUPABASE_URL production
vercel env pull .env.local   # pulls Development values (add --environment=production for prod)

Fix 2: use the right prefix for browser code

// Next.js: inlined at BUILD time, visible in the browser
const url = process.env.NEXT_PUBLIC_SUPABASE_URL!;

// Vite
const url = import.meta.env.VITE_SUPABASE_URL;

Public prefixes are baked in at build time, which is another reason a redeploy is required.

Fix 3: keep secrets server-side

Secret keys (SUPABASE_SERVICE_ROLE_KEY, OPENAI_API_KEY, STRIPE_SECRET_KEY) must not get a public prefix. Anything with NEXT_PUBLIC_ or VITE_ ends up in the JavaScript sent to every visitor. Use secrets only in Route Handlers, Server Actions or API routes:

// app/api/chat/route.ts
export async function POST(req: Request) {
  const key = process.env.OPENAI_API_KEY; // server only
  // ...
}

Fix 4: fail fast with a clear message

function requireEnv(name: string) {
  const v = process.env[name];
  if (!v) throw new Error(`Missing env var: ${name}`);
  return v;
}

For NEXT_PUBLIC_ variables in client code, reference them literally (process.env.NEXT_PUBLIC_X). Dynamic lookups like process.env[name] aren't inlined in the browser.

Fix 5: check the value itself

Re-copy the key from the provider dashboard. Remove quotes and trailing spaces. Make sure it's the key for the right project (for example, the Supabase anon or sb_publishable_… key in the client, never the service role or sb_secret_… key).

FAQ

I added it but it's still undefined. Did you redeploy? Is it ticked for Production?

Is the Supabase anon key safe to expose? It's designed to be public, but only if Row Level Security is enabled on your tables.

Originally published on FixKit AI. Deploy failing for a different reason? See why v0/Bolt apps fail on Vercel, or paste the error into the free FixKit Error Fixer (disclosure: I built it).