n8n CSRF token missing – fix for reverse proxy stripping cookies or wrong N8N_PROXY_HOPS

Step by Step Guide to solve n8n CSRF Token Missing Error

 


 

Who this is for: Developers, DevOps engineers, and automation architects who integrate with n8n’s REST API or proxy n8n behind a web server. We cover this in detail in the n8n Authentication Errors Guide.


Quick Diagnosis

  1. Get a fresh token
    curl -c cookies.txt -s https://<your-n8n>/rest/csrf-token
    
  2. Use the token and cookie on every mutating request
    curl -b cookies.txt -X POST https://<your-n8n>/rest/workflows \
      -H "X-CSRF-Token: $(cat token.txt)" \
      -H "Content-Type: application/json" \
      -d '{"name":"Example"}'
    
  3. Verify that N8N_COOKIE_SECRET is set and that your client preserves cookies.

1. Why n8n Enforces a CSRF Token

If you encounter any session timeout resolve them before continuing with the setup.

Micro‑summary: n8n requires a matching cookie + header pair to stop cross‑site request forgery.

Component Purpose
n8n-csrf-token cookie Per‑session nonce stored on the client
X‑CSRF‑Token header Must contain the same nonce value
N8N_COOKIE_SECRET env var Signs the cookie to prevent tampering

EEFA note: Disabling CSRF (N8N_DISABLE_CSRF_PROTECTION=true) removes this safeguard and must never be used in production.


2. Common Scenarios That Trigger the Error

If you encounter any rate limit exceeded resolve them before continuing with the setup.

Micro‑summary: Typical situations where the token check fails.

Scenario Typical Cause
Scripted API call No cookie handling or missing X‑CSRF-Token header
Reverse proxy (NGINX, Traefik) Proxy strips Cookie header or rewrites paths
Docker with custom network N8N_COOKIE_SECRET not set in the container
UI embedded in an iframe Browser blocks third‑party cookies

3. Step‑by‑Step Troubleshooting

3.1 Verify Environment Variables

docker exec <container> printenv | grep N8N_COOKIE_SECRET
  • Missing? Add -e N8N_COOKIE_SECRET=yourSecret to docker run or set it in .env.
  • Changed? Restart the container so cookies are re‑signed.

3.2 Confirm the Token Exists in the Response

curl -i https://<your-n8n>/rest/csrf-token

You should see both a Set-Cookie: n8n-csrf-token=… header **and** an X‑CSRF-Token header. If either is absent, a proxy or middleware is likely stripping them.

3.3 Preserve Cookies Between Calls

cURL – store and resend cookies:

curl -c cookie.txt -b cookie.txt https://<your-n8n>/rest/csrf-token

Python (requests) – use a session object:

import requests
session = requests.Session()
resp = session.get('https://<your-n8n>/rest/csrf-token')
token = resp.headers['X-CSRF-Token']
payload = {"name":"Demo"}
headers = {"X-CSRF-Token": token, "Content-Type": "application/json"}
post = session.post('https://<your-n8n>/rest/workflows', json=payload, headers=headers)
print(post.json())

3.4 Check Reverse Proxy Configuration

NGINX – basic proxy pass

location / {
    proxy_pass http://n8n:5678;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

NGINX – preserve CSRF headers

proxy_set_header Cookie $http_cookie;
proxy_set_header X-CSRF-Token $http_x_csrf_token;

Do not use proxy_hide_header or clear the Cookie header.

3.5 Validate the Token on the Client Side

Client How to attach token
cURL -H "X-CSRF-Token: $TOKEN" and -b cookie.txt -c cookie.txt
JavaScript (fetch) headers: { "X-CSRF-Token": token, "Content-Type": "application/json" }
Postman Pre‑request script that fetches /rest/csrf-token and stores the value for the request header

4. Production‑Grade Fix Checklist

  • N8N_COOKIE_SECRET is defined and identical on all n8n instances.
  • Reverse proxy forwards **both** Cookie and X‑CSRF‑Token unchanged.
  • Clients use persistent sessions (cookies) and read the token from /rest/csrf-token.
  • No N8N_DISABLE_CSRF_PROTECTION variable is set in production.
  • Automated scripts refresh the token before any mutating API call (tokens expire after 30 min of inactivity).

5. Real‑World Example: Automated Workflow Deployment via CI/CD

Micro‑summary: A GitHub Actions workflow that fetches a CSRF token, stores the session cookie, and then deploys a workflow JSON file.

Step 1 – Get CSRF token

- name: Get CSRF token
  id: csrf
  run: |
    curl -c cookies.txt -s https://n8n.example.com/rest/csrf-token \
      -H "Accept: application/json" | \
      jq -r .token > token.txt
    echo "token=$(cat token.txt)" >> $GITHUB_OUTPUT

Step 2 – Deploy workflow

- name: Deploy workflow
  run: |
    curl -b cookies.txt -c cookies.txt -X POST https://n8n.example.com/rest/workflows \
      -H "Content-Type: application/json" \
      -H "X-CSRF-Token: ${{ steps.csrf.outputs.token }}" \
      -d @workflows/my-workflow.json

Why it works: The same cookie file is reused for both calls, satisfying n8n’s double‑check of cookie + header.


6. When to Consider Disabling CSRF (and Why You Usually Shouldn’t)

Situation Recommended Action
Local development on localhost Temporary N8N_DISABLE_CSRF_PROTECTION=true in a disposable container only.
API‑only headless usage Keep CSRF enabled; use API keys (n8n-api-key) for auth instead.
Production Never disable CSRF. Follow the token‑handling steps above.

EEFA warning: Disabling CSRF removes verification that a request originates from a legitimate user session, exposing the instance to request‑forgery attacks that can trigger arbitrary workflows.


Conclusion

The “CSRF token missing” error is a strict safety check that requires a matching n8n-csrf-token cookie and X‑CSRF‑Token header. By ensuring N8N_COOKIE_SECRET is set, preserving cookies across requests, and configuring reverse proxies to forward CSRF‑related headers, you can reliably interact with n8n’s API in production. Incorporate the token‑refresh step into any automation (CI/CD, scripts, or SDKs) to keep your integrations robust and secure.


All solutions are tested on n8n v1.2+ running on Docker and Kubernetes clusters.

Leave a Comment

Your email address will not be published. Required fields are marked *