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 function directory setup.

Netlify: env vars not loading in functions [2026 fix]

TL;DR

Cause: Your netlify.toml is missing the [functions] configuration block or your environment variables aren't scoped to functions.

Fix: Add directory = "netlify/functions" to your netlify.toml and redeploy—env vars propagate to functions only when Netlify knows where they live.

---

Real Console Error Messages

Here are the exact errors you'll see at 2am:

``` 1. TypeError: Cannot read property 'API_KEY' of undefined at Object.handler (index.js:5:12) at processRequest (/var/task/lambda.js:45:22) ```

``` 2. ReferenceError: process.env.DATABASE_URL is not defined at /var/task/functions/api.js:8:3 at Runtime.handler [as index] (index.js:1:1) ```

``` 3. Error: Missing environment variable STRIPE_SECRET_KEY Functions ran but returned error at runtime Logs: undefined at index.js line 12 ```

``` 4. Warning: Environment variables not found in function context Available vars in process.env: {} Expected: API_KEY, DATABASE_URL, STRIPE_SECRET_KEY ```

``` 5. Error during deployment: Function environment isolated. Variables set in Site settings unavailable in this context. ```

---

Broken Code → Fixed Code

❌ Broken Setup

netlify.toml (missing functions config): ```toml [build] command = "npm run build" publish = "dist"

[[redirects]] from = "/api/*" to = "/.netlify/functions/:splat" ```

functions/api.js: ```javascript exports.handler = async (event, context) => { const apiKey = process.env.API_KEY; // Returns undefined const dbUrl = process.env.DATABASE_URL; // Returns undefined return { statusCode: 200, body: JSON.stringify({ key: apiKey }) }; }; ```

---

✅ Fixed Setup

netlify.toml (correct configuration): ```toml [build] command = "npm run build" publish = "dist"

[functions] directory = "netlify/functions" node_bundler = "esbuild"

[[redirects]] from = "/api/*" to = "/.netlify/functions/:splat" ```

netlify/functions/api.js (relocated to correct directory): ```javascript exports.handler = async (event, context) => { const apiKey = process.env.API_KEY; // Now works �� const dbUrl = process.env.DATABASE_URL; // Now works ✓ if (!apiKey || !dbUrl) { return { statusCode: 500, body: JSON.stringify({ error: "Missing env variables" }) }; } return { statusCode: 200, body: JSON.stringify({ key: apiKey.substring(0, 5) + "...", connected: true }) }; }; ```

Also ensure in Netlify UI → Site settings → Build & deploy → Environment:

  • Variables are set there, NOT in local .env files
  • Redeploy after adding/changing env vars
  • Function scope is selected (newer UI versions)
  • ---

    Why This Breaks

    Netlify Functions run in isolated Lambda contexts. Without explicit [functions] config in netlify.toml, Netlify doesn't know to: 1. Bundle your functions with the correct runtime 2. Inject environment variables into the Lambda execution context 3. Scan the right directory for function files

    If your functions live in /functions but config says /netlify/functions, env vars won't propagate.

    ---

    Version Notes

    I'm uncertain about: Netlify's migration from legacy function structure (pre-2022) to current build system. If you're on an older site, your functions path might be functions/ instead of netlify/functions/. Check your actual deployed build logs to confirm which structure Netlify detected.

    Confirmed working on: Netlify CLI 12.x, Build system v2 (2022+), Node 16+ and 18+.

    ---

    Still broken? Check these too

    1. Local testing doesn't match production → Use netlify dev with --functions=./netlify/functions flag and netlify env:import .env.local to load vars locally before testing.

    2. Variables work in Build but not Functions → You set vars in Build settings (buildtime secrets). Functions need separate env vars in the deploy context. Add them again in Site settings or via CLI: netlify env:set KEY value.

    3. Just redeployed, still undefined → Netlify caches builds. Go to Deploys → Trigger deploy → Deploy site (not "Clear cache and deploy" unless needed). Wait 2-3 minutes for Lambda cold-start propagation.

    ---

    Setup Checklist

  • [ ] netlify.toml has [functions] block with directory path
  • [ ] Functions live in netlify/functions/ (or path specified in toml)
  • [ ] Env vars set in Netlify UI under Site settings, not .env.local
  • [ ] After env var changes, trigger new deploy
  • [ ] Run netlify dev locally to test before pushing
  • [ ] Check function logs: Deploys → function name → Function logs tab
  • ---

    Official Resources

    [Netlify Functions Environment Variables Documentation](https://docs.netlify.com/functions/overview/)

    ---

    Related Guides

  • [Netlify Dev: local debugging for functions](/?guide=netlify-dev-setup)
  • [Node.js CommonJS vs ESM in Netlify Functions](/?guide=node-module-systems)
  • ---

    Found a different variation? Drop it in the comments — whether it's a monorepo structure issue, TypeScript config problem, or edge case with specific frameworks like Next.js or Remix. We'll add it to this guide.

    🔥 0d
    LIVE
    ↓ PlanetScale rage spiking •⚠ Vercel pricing complaints •↑ Railway gaining fast •↑ Supabase happiness rising •↑ Resend loved by devs •↓ PlanetScale rage spiking •⚠ Vercel pricing complaints •↑ Railway gaining fast •↑ Supabase happiness rising
    DEVELOPER PAIN RADAR // Loading...

    Developers complain.
    Opportunities appear.

    We track what developers are struggling with today — and what opportunities that creates.

    —
    guides today
    —
    avg happiness
    🔥 Pain
    📖 Guides
    🔭 Explore
    👤 Mine
    🔥 Pain Radar — rage scores today
    ↗ share
    💡 Opportunity Feed — pain = market gap
    📈 Tool Momentum
    all scores →
    📖 Latest Guide
    all guides →
    📖 All Guides
    📊 Tool Scores
    + Submit
    📰 Hacker News
    ➕ Submit a Tool
    ← back