Netlify: env vars not loading in functions [2026 fix]
Environment variables aren't accessible in Netlify Functions due to missing netlify.toml config or incorrect variable scoping—redeploy after adding [functions] environment settings.
Netlify: env vars not loading in functions [2026 fix]
TL;DR
Cause: Environment variables defined in Netlify UI aren't automatically injected into serverless functions without explicitnetlify.toml configuration.
Fix: Add [functions] section to netlify.toml or redeploy after setting variables in UI.---
Real Console Error Messages
Here are exact error outputs you'll see at 2am:
``` TypeError: Cannot read property 'API_KEY' of undefined at Runtime.handler (/var/task/functions/api.js:5:12) at Runtime.handleRequest (/var/runtime/index.js:890:12) ```
``` ReferenceError: process.env.STRIPE_SECRET is not defined at Object.<anonymous> (/var/task/functions/stripe-webhook.js:12:3) ```
``` {"errorMessage":"Environment variable DATABASE_URL returned undefined","errorType":"TypeError"} ```
``` Function execution took 5000ms and timed out. Checking process.env logs shows: {} ```
``` Warning: Missing required environment variable OPENAI_API_KEY in function context Function will fail at line 23 during runtime ```
---
Broken Code vs. Fixed Code
❌ BROKEN: Depending on env vars without netlify.toml
```javascript // netlify/functions/api.js exports.handler = async (event) => { const apiKey = process.env.API_KEY; // undefined! const dbUrl = process.env.DATABASE_URL; // undefined! return { statusCode: 500, body: JSON.stringify({ error: "Missing credentials" }) }; }; ```
```toml
netlify.toml (INCOMPLETE - missing [functions] block)
[build] command = "npm run build" functions = "netlify/functions" ```✅ FIXED: Explicit function environment configuration
```toml
netlify.toml (CORRECT)
[build] command = "npm run build" functions = "netlify/functions"[functions] node_bundler = "esbuild" # Option A: Reference UI-defined variables # (Already set in Netlify Dashboard → Site settings → Build & deploy → Environment)
OR Option B: Define directly in netlify.toml
[functions.api] environment = ["API_KEY", "DATABASE_URL"][functions.stripe] environment = ["STRIPE_SECRET", "STRIPE_PUBLIC"] ```
```javascript // netlify/functions/api.js (NO CHANGES NEEDED - netlify.toml fixes it) exports.handler = async (event) => { const apiKey = process.env.API_KEY; // Now defined! ✓ const dbUrl = process.env.DATABASE_URL; // Now defined! ✓ if (!apiKey || !dbUrl) { return { statusCode: 500, body: JSON.stringify({ error: "Env vars still missing" }) }; } return { statusCode: 200, body: JSON.stringify({ success: true }) }; }; ```
---
Version-Specific Notes
⚠️ We're uncertain about exact behavior differences in Netlify Functions between 2024 and 2026 runtimes. Test your specific Node version:
[functions] block syntax shown aboveenvironment array instead of object syntaxAlways verify by checking your package.json engines field and Netlify's runtime logs.
---
Still broken? Check these too
1. Variables set in UI but not persisted: Navigate to Site settings → Environment variables. Verify all keys are listed. Common mistake: setting them, forgetting to click "Save." After adding/changing, you must redeploy (even with no code changes) for functions to see them.
2. Function scoping conflict: If you have context-specific env vars (like [functions.specific-function]), those *override* global [functions] settings. Check your netlify.toml for function-specific blocks that might be missing your variable. Use netlify env:list CLI command to debug.
3. ESM vs CommonJS module format: If using export const handler (ESM), some older Netlify runtimes require a netlify.toml directive: add node_bundler = "esbuild" under [functions]. ESM env vars sometimes resolve differently. See [environment variables guide](/guide=netlify-esm-env).
4. Build-time vs runtime confusion: Environment variables injected at build time (for Next.js, Gatsby) are *different* from runtime function env vars. Your frontend build might succeed while functions still fail. Isolate the issue with console.log(process.env) in the function handler.
5. Netlify CLI local mismatch: Running netlify dev locally may not load .env into functions. Use .env.example for reference and explicitly pass env vars: API_KEY=test netlify dev
---
Redeploy Strategy
After fixing netlify.toml:
1. Commit changes: git add netlify.toml && git commit -m "Fix: add [functions] env config"
2. Push to your connected branch (GitHub, GitLab, etc.)
3. Netlify auto-redeploys—watch the deploy log
4. Check function execution in Netlify Functions logs (Site → Functions)
5. Test: curl https://your-site/.netlify/functions/api
---
Official Resources
📚 [Netlify Functions Environment Variables](https://docs.netlify.com/functions/overview/#environment-variables) 📚 [netlify.toml Reference](https://docs.netlify.com/configure-builds/file-conventions/) 🔗 [Related: Debugging Netlify deployments](/guide=netlify-deploy-debug) 🔗 [Related: Next.js env var patterns](/guide=nextjs-env-secrets)
---
Found a different variation? Drop it in the comments — whether it's a monorepo structure, custom framework, or edge cases like TypeScript function definitions, your fix could save someone else's 2am panic.