6.4 KiB
N8N API Key Mismatch - 401 Unauthorized
🔍 Problem Identified
Error: 401 - "Unauthorized"
Log: Invalid API key { received: 'present', expected: 'configured' }
Status:
- ✅ Endpoint is being called (
Mission Created Webhook Received) - ✅ API key is being sent (
received: 'present') - ❌ API key values don't match
🔍 Root Cause
The API key sent by N8N in the x-api-key header does not match the N8N_API_KEY environment variable on the server.
How It Works
-
Server sends to N8N (line 420 in
app/api/missions/route.ts):config: { N8N_API_KEY: process.env.N8N_API_KEY, // From server environment MISSION_API_URL: process.env.NEXT_PUBLIC_API_URL } -
N8N uses this value in "Save Mission To API" node:
x-api-key: {{ $node['Process Mission Data'].json.config.N8N_API_KEY }} -
Server receives and validates (line 42 in
app/api/missions/mission-created/route.ts):if (apiKey !== expectedApiKey) { // Keys don't match → 401 error }
The Problem
If process.env.N8N_API_KEY is undefined or empty when sending to N8N:
- N8N receives
undefinedor empty string - N8N sends empty string in header
- Server expects the actual key value
- Keys don't match → 401 error
✅ Solution
Step 1: Verify N8N_API_KEY is Set
Check your environment variables:
# In your terminal (if running locally)
echo $N8N_API_KEY
# Or check in your application
# Create a test endpoint to verify
Expected: Should show the actual API key value (not empty)
Step 2: Ensure Same Key in Both Places
The key must be the same in:
- Server environment variable:
N8N_API_KEY=your-key-here - N8N workflow config: The value sent in
config.N8N_API_KEY
If they're different, they won't match!
Step 3: Check What N8N is Sending
In N8N workflow "Save Mission To API" node, verify:
-
Header
x-api-keyvalue:{{ $node['Process Mission Data'].json.config.N8N_API_KEY }} -
What this resolves to:
- If
config.N8N_API_KEYisundefined→ N8N sends empty string - If
config.N8N_API_KEYhas a value → N8N sends that value
- If
-
Check N8N execution logs:
- Look at the actual request being sent
- Check the
x-api-keyheader value - Compare with your server's
N8N_API_KEY
Step 4: Fix the Mismatch
Option A: If server's N8N_API_KEY is undefined
Add to .env.local (or production environment):
N8N_API_KEY=LwgeE1ntADD20OuWC88S3pR0EaO7FtO4
Restart the application.
Option B: If N8N is sending wrong value
Check what value N8N has in config.N8N_API_KEY:
- It should match the server's
N8N_API_KEY - If different, update one to match the other
Option C: Hardcode in N8N (not recommended)
If you can't sync the values, you could hardcode in N8N:
x-api-key: LwgeE1ntADD20OuWC88S3pR0EaO7FtO4
But this is less secure - better to use environment variable.
🧪 Testing
Test 1: Check Server Environment
Create test endpoint:
// app/api/test-n8n-key/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({
hasN8NApiKey: !!process.env.N8N_API_KEY,
keyLength: process.env.N8N_API_KEY?.length || 0,
keyPrefix: process.env.N8N_API_KEY ? process.env.N8N_API_KEY.substring(0, 4) + '...' : 'none'
});
}
Visit: http://localhost:3000/api/test-n8n-key
Expected:
{
"hasN8NApiKey": true,
"keyLength": 32,
"keyPrefix": "Lwge..."
}
Test 2: Check What N8N Sends
In N8N execution logs, check the "Save Mission To API" node:
- Look at the request headers
- Find
x-api-keyheader - Note the value
Compare with server's N8N_API_KEY - they must match exactly.
Test 3: Manual Test
Test the endpoint with the correct key:
curl -X POST https://hub.slm-lab.net/api/missions/mission-created \
-H "Content-Type: application/json" \
-H "x-api-key: LwgeE1ntADD20OuWC88S3pR0EaO7FtO4" \
-d '{
"missionId": "test-id",
"name": "Test",
"creatorId": "user-id"
}'
Expected: 200 OK (if mission exists) or 404 (if mission doesn't exist)
If 401: The key in the curl command doesn't match server's N8N_API_KEY
🔧 Common Issues
Issue 1: Key is undefined when sending to N8N
Symptom: N8N receives undefined or empty string in config.N8N_API_KEY
Cause: process.env.N8N_API_KEY is not set when creating mission
Fix: Add N8N_API_KEY to environment and restart
Issue 2: Different keys in different environments
Symptom: Works in development but not production (or vice versa)
Cause: Different N8N_API_KEY values in different environments
Fix: Use the same key in all environments, or update N8N to use environment-specific keys
Issue 3: Key has extra spaces or characters
Symptom: Keys look the same but don't match
Cause: Extra spaces, newlines, or special characters
Fix:
# Correct
N8N_API_KEY=LwgeE1ntADD20OuWC88S3pR0EaO7FtO4
# Wrong (with quotes)
N8N_API_KEY="LwgeE1ntADD20OuWC88S3pR0EaO7FtO4"
# Wrong (with spaces)
N8N_API_KEY = LwgeE1ntADD20OuWC88S3pR0EaO7FtO4
📋 Debugging Checklist
N8N_API_KEYis set in server environment- Key value matches what N8N is sending
- No extra spaces or characters in key
- Server has been restarted after adding key
- Test endpoint shows key is loaded
- N8N execution logs show correct key in header
- Manual curl test works with the key
🎯 Expected Flow After Fix
- Mission created ✅
- N8N workflow triggered ✅
- Server sends
config.N8N_API_KEYto N8N ✅ - N8N creates integrations ✅
- N8N calls
/api/missions/mission-created✅ - N8N sends
x-api-keyheader with same value ✅ - Server validates key matches ✅
- IDs saved to database ✅
📝 Summary
Problem: 401 Unauthorized - API key mismatch
Root Cause: The API key sent by N8N doesn't match the server's N8N_API_KEY
Solution:
- Ensure
N8N_API_KEYis set in server environment - Ensure N8N uses the same key value
- Verify keys match exactly (no spaces, same value)
After Fix: The endpoint should return 200 OK and save integration IDs.
Document Created: $(date) Priority: CRITICAL - Blocks integration IDs from being saved