Netlify: env vars not loading in functions [2026 fix]
Env vars undefined in Netlify Functions? Deploy with netlify.toml config and expose vars explicitly—one deploy fixes it.
Netlify: env vars not loading in functions [2026 fix]
TL;DR
Cause: Environment variables aren't automatically available to Netlify Functions without explicit configuration innetlify.toml.
Fix: Add environment table to netlify.toml and redeploy—variables will load in process.env immediately.---
Real Console Error Messages
Here are exact errors you'll see at 2am:
``` 1. TypeError: Cannot read property 'API_KEY' of undefined at Object.<anonymous> (/var/task/functions/api.js:12:5) 2. ReferenceError: process is not defined at eval (webpack:///./functions/query.js?:5:1) 3. Error: env var STRIPE_SECRET_KEY is undefined in function at Handler (/var/task/functions/stripe-webhook.js:8:15) 4. undefined is not a function (checking if process.env.DATABASE_URL exists) at connectDB (/var/task/functions/db.js:3:2) 5. Warning: Using process.env.VARIABLE directly without fallback Function invoked but returned: null (logs show undefined value) ```
---
Broken Code vs. Fixed Code
❌ BROKEN: Missing netlify.toml configuration
File structure: ``` project/ ├── netlify.toml (empty or missing env section) ├── .env (local only, ignored in production) └── functions/ └── api.js ```
functions/api.js: ```javascript const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); // process.env.STRIPE_SECRET_KEY is undefined in production
exports.handler = async (event) => { return { statusCode: 200, body: JSON.stringify({ key: process.env.API_KEY }) // Returns: { key: undefined } }; }; ```
Result: Functions work locally (because .env loads) but fail in production.
---
✅ FIXED: netlify.toml with environment configuration
netlify.toml: ```toml [build] command = "npm run build" functions = "functions" publish = "dist"
[functions] node_bundler = "esbuild"
Expose environment variables to functions
[functions.api] environment = ["STRIPE_SECRET_KEY", "API_KEY", "DATABASE_URL"][[redirects]] from = "/api/*" to = "/.netlify/functions/:splat" status = 200 ```
functions/api.js (identical code now works): ```javascript const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); // STRIPE_SECRET_KEY now defined from netlify.toml
exports.handler = async (event) => { return { statusCode: 200, body: JSON.stringify({ key: process.env.API_KEY }) // Returns: { key: "your-actual-key-value" } }; }; ```
Steps to deploy:
1. Add/update netlify.toml with [functions.FUNCTION_NAME] and environment list
2. Set variables in Netlify UI: Site Settings > Build & Deploy > Environment
3. Run: git push (redeploy triggers automatically)
4. Verify in Netlify Function logs (Functions tab shows env vars loaded)
---
Version-Specific Notes
I'm uncertain whether Netlify's auto-detection of undeclared env vars changed between 2024-2026. If you're using Netlify Functions v1.x (pre-2025), explicitly listing vars in netlify.toml is required. On v2.x behavior, docs are unclear on whether vars passed to UI auto-expose—to be safe, always declare them in netlify.toml. Test locally with netlify dev first.
---
Still Broken? Check These Too
1. .env file committed to git → Remove from repo, use Netlify UI only. Local .env never syncs to production. [Related: Secrets management guide](/?guide=netlify-secrets)
2. Function name mismatch in netlify.toml → You wrote [functions.webhook] but file is stripe-webhook.js. Keep function names consistent. Check netlify.toml function name matches filename without .js.
3. Environment vars set but functions still see undefined → Redeploy is required. Changing UI settings doesn't restart existing function instances. Push an empty commit: git commit --allow-empty -m "redeploy" && git push.
4. Using process.env in build-time code (not runtime) → Build-time vars need different config. This guide covers runtime function vars only. [Related: Build environment variables](/?guide=netlify-build-env)
---
Quick Checklist
netlify.toml exists in project root[functions.YOURFUNCTIONNAME] section added with environment listnetlify.toml and Netlify UInetlify dev shows vars in function logsnetlify.toml changes---
Official References
---
Found a different variation? Drop it in the comments—especially if you hit this with edge cases like: