Netlify: env vars not loading in functions [2026 fix]
Env vars undefined in Netlify Functions? Deploy your netlify.toml config and rebuild—Functions don't read .env files at runtime.
TL;DR
Cause: Netlify Functions execute in a sandboxed environment that doesn't automatically load.env files; you must declare variables in netlify.toml or Netlify UI.
Fix: Add your environment variables to netlify.toml under [functions] or set them via Netlify dashboard, then redeploy.---
Common Error Messages
Here are exact console outputs you'll see at 2am:
``` Uncaught ReferenceError: process.env.STRIPE_KEY is not defined at /var/task/stripe-handler.js:12:15 ```
``` TypeError: Cannot read property 'API_URL' of undefined at Object.<anonymous> (/var/task/.netlify/functions/api-proxy.js:3:5) ```
``` Failed to initialize: process.env.DATABASE_URL returned undefined Environment not available in function context ```
``` ERR: Your function tried to access process.env.JWT_SECRET but it's not in the Netlify runtime. ```
``` [ERROR] Runtime error in function at deployment: REACT_APP_API is undefined ```
---
Broken vs. Fixed Code
❌ BROKEN: Relying on .env file
```javascript // netlify/functions/stripe-webhook.js require('dotenv').config();
const stripe = require('stripe')(process.env.STRIPE_KEY); // ↑ Returns undefined because .env isn't loaded in Netlify runtime
exports.handler = async (event) => { return { statusCode: 200, body: 'OK' }; }; ```
✅ FIXED: Variables declared in netlify.toml
```toml
netlify.toml
[build] command = "npm run build" functions = "netlify/functions"[functions] node_bundler = "esbuild"
[[functions]] name = "stripe-webhook" environment = { STRIPE_KEY = "sk_live_...", NODE_ENV = "production" } ```
```javascript // netlify/functions/stripe-webhook.js const stripe = require('stripe')(process.env.STRIPE_KEY); // ✓ Now properly available from netlify.toml
exports.handler = async (event) => { const session = await stripe.checkout.sessions.create({...}); return { statusCode: 200, body: JSON.stringify(session) }; }; ```
---
Why This Happens
Netlify Functions run in AWS Lambda-based containers. The .env file exists only on your local machine and in your Git repository (if accidentally committed—don't do that). At deployment:
1. Your code is deployed but .env stays local
2. Function runtime spins up without access to .env
3. process.env.YOUR_VAR returns undefined
4. Your app crashes at 2am
Version note: This behavior is consistent across Netlify Functions from 2024–2026 and applies to Node.js 18.x, 20.x, and 22.x runtimes.
---
Solution: Three Working Methods
Method 1: netlify.toml (Recommended for development)
```toml [[functions]] name = "api-proxy" environment = { API_URL = "https://api.example.com", API_KEY = "key_123" } ```
Method 2: Netlify UI Dashboard
1. Site settings → Build & deploy → Environment 2. Click "Edit variables" 3. Add key-value pairs (available to all functions) 4. Redeploy site
Method 3: Netlify CLI
```bash netlify env:set STRIPE_KEY sk_live_xxx netlify deploy --prod ```
---
Critical: Verify Your Deploy
After pushing changes:
```bash
Check that netlify.toml is committed
git log --oneline netlify.tomlTrigger rebuild
netlify deploy --prod --triggerCheck function logs
netlify functions:invoke stripe-webhook --identity ```Deploy logs should show your variables loaded. If you see undefined, the build didn't pick up your changes—verify Git committed netlify.toml.
---
Still broken? Check these too
1. [Syntax error in netlify.toml](/?guide=toml-validation) — Invalid TOML prevents entire config from loading. Use a TOML validator or npm install -D toml to test parsing.
2. Secrets vs. environment variables — Sensitive values (API keys, tokens) should be set via Netlify UI *and* added to [context.production] to prevent exposure in build logs. Never commit secrets to Git or netlify.toml.
3. [Function bundling config mismatch](/?guide=netlify-bundler) — If using a custom bundler (esbuild, webpack), ensure it preserves process.env references and doesn't tree-shake them out as "unused".
---
Official Resources
---
Quick Checklist
netlify.toml [functions] section OR Netlify UIrequire('dotenv').config() calls (not needed)netlify.toml to Gitnetlify functions:invoke function-nameprocess.env.VAR_NAME is no longer undefinedFound a different variation? Drop it in the comments.