261 lines
6.4 KiB
Markdown
261 lines
6.4 KiB
Markdown
# 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
|
|
|
|
1. **Server sends to N8N** (line 420 in `app/api/missions/route.ts`):
|
|
```typescript
|
|
config: {
|
|
N8N_API_KEY: process.env.N8N_API_KEY, // From server environment
|
|
MISSION_API_URL: process.env.NEXT_PUBLIC_API_URL
|
|
}
|
|
```
|
|
|
|
2. **N8N uses this value** in "Save Mission To API" node:
|
|
```
|
|
x-api-key: {{ $node['Process Mission Data'].json.config.N8N_API_KEY }}
|
|
```
|
|
|
|
3. **Server receives and validates** (line 42 in `app/api/missions/mission-created/route.ts`):
|
|
```typescript
|
|
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 `undefined` or 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**:
|
|
|
|
```bash
|
|
# 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**:
|
|
|
|
1. **Server environment variable**: `N8N_API_KEY=your-key-here`
|
|
2. **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:
|
|
|
|
1. **Header `x-api-key` value**:
|
|
```
|
|
{{ $node['Process Mission Data'].json.config.N8N_API_KEY }}
|
|
```
|
|
|
|
2. **What this resolves to**:
|
|
- If `config.N8N_API_KEY` is `undefined` → N8N sends empty string
|
|
- If `config.N8N_API_KEY` has a value → N8N sends that value
|
|
|
|
3. **Check N8N execution logs**:
|
|
- Look at the actual request being sent
|
|
- Check the `x-api-key` header 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):
|
|
```env
|
|
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**:
|
|
```typescript
|
|
// 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**:
|
|
```json
|
|
{
|
|
"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-key` header
|
|
- 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**:
|
|
```bash
|
|
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**:
|
|
```env
|
|
# Correct
|
|
N8N_API_KEY=LwgeE1ntADD20OuWC88S3pR0EaO7FtO4
|
|
|
|
# Wrong (with quotes)
|
|
N8N_API_KEY="LwgeE1ntADD20OuWC88S3pR0EaO7FtO4"
|
|
|
|
# Wrong (with spaces)
|
|
N8N_API_KEY = LwgeE1ntADD20OuWC88S3pR0EaO7FtO4
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 Debugging Checklist
|
|
|
|
- [ ] `N8N_API_KEY` is 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
|
|
|
|
1. **Mission created** ✅
|
|
2. **N8N workflow triggered** ✅
|
|
3. **Server sends `config.N8N_API_KEY` to N8N** ✅
|
|
4. **N8N creates integrations** ✅
|
|
5. **N8N calls `/api/missions/mission-created`** ✅
|
|
6. **N8N sends `x-api-key` header with same value** ✅
|
|
7. **Server validates key matches** ✅
|
|
8. **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**:
|
|
1. Ensure `N8N_API_KEY` is set in server environment
|
|
2. Ensure N8N uses the same key value
|
|
3. 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
|
|
|