Hosto

Sign In

n8n Webhooks Not Working? The Complete Troubleshooting Guide (2026)

By Tushar Khatri

Monitor showing syntax-highlighted source code with line numbers

If your n8n webhook is not working, you are in good company: webhook issues are the single most common support question in the n8n community, and almost all of them come down to a handful of predictable failure modes. The frustrating part is that n8n webhooks fail silently from the sender's point of view: Stripe, Telegram, or your custom app fires a request into the void, gets a 404 or a timeout, and your workflow never runs. No error in n8n, because n8n never saw the request.

The good news: every one of these failures has a clear symptom and a clear fix. This guide walks through them problem by problem, from the classic test-vs-production URL mixup to the sneakier reverse proxy and Cloudflare issues that bite self-hosters. Work through them in order. They are sorted from most to least common.

Problem 1: You're calling the wrong URL (test vs. production)

Symptom: The webhook returns a 404 with a message like "webhook is not registered," even though the workflow looks perfectly fine in the editor.

Cause: Every Webhook node in n8n exposes two different URLs, and they are live at completely different times:

  • Test URL (contains /webhook-test/): only active while you are actively listening in the editor, that is, after you click "Listen for test event" or "Execute workflow." It handles one request, shows you the data in the editor, and then stops listening.
  • Production URL (contains /webhook/): only active once the workflow itself is activated (the toggle in the top-right of the editor). An inactive workflow's production URL simply does not exist as far as n8n is concerned.

The most common beginner mistake with n8n webhooks is registering the production URL with a third-party service while the workflow is still inactive, or the mirror image, hardcoding the test URL somewhere and wondering why it only ever works once, and only while the editor tab is open.

Fix:

  1. For development: click "Listen for test event," then fire your request at the Test URL. Repeat for every test call. It disarms after each one.
  2. For real traffic: flip the workflow to Active, and make sure the external service is calling the Production URL.
  3. Double-check which URL you pasted into the third-party service. /webhook-test/ in a Stripe or Telegram config is always wrong.

Problem 2: WEBHOOK_URL isn't set (reverse proxy / tunnel setups)

Symptom: Webhooks work when you curl your public domain manually, but the URLs n8n displays (and the URLs it registers with services like Telegram) point at localhost:5678 or an internal hostname that nothing outside your server can reach.

Cause: n8n builds webhook URLs from its own host and port. If n8n runs behind a reverse proxy (Nginx, Caddy, Traefik) or a tunnel, it has no idea what its public address is unless you tell it. The result: n8n hands out http://localhost:5678/webhook/... style URLs, external services dutifully try to call them, and the requests never resolve.

Fix: Set the WEBHOOK_URL environment variable to your public HTTPS URL and restart n8n:

WEBHOOK_URL=https://n8n.yourdomain.com/

Or in Docker Compose:

environment:
  - WEBHOOK_URL=https://n8n.yourdomain.com/

After restarting, open the Webhook node and confirm the displayed URLs now use your public domain. For trigger nodes that register their own webhooks (Telegram, and similar), deactivate and reactivate the workflow so they re-register with the corrected URL. If you are setting up a server from scratch, our guide on how to self-host n8n covers the full reverse proxy configuration.

Problem 3: Reverse proxy misconfiguration

Symptom: Webhooks reach n8n but behave strangely: redirects go to the wrong scheme, large payloads get rejected with 413 Payload Too Large, or long-running workflows die with a 502/504 from the proxy.

Cause: Three distinct proxy problems tend to cluster together:

  1. Missing or wrong proxy headers. The proxy must pass the original Host and forwarding headers through, or n8n misinterprets where requests came from.
  2. Proxy timeouts shorter than workflow execution time. If your workflow takes 90 seconds and Nginx's default proxy timeout is 60, the sender gets a 504 even though the workflow may keep running.
  3. Body size limits. Nginx defaults to a 1 MB request body cap. Webhook payloads carrying files or large JSON get bounced before n8n ever sees them.

Fix: For Nginx, a sane baseline looks like:

location / {
    proxy_pass http://localhost:5678;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 300s;
    client_max_body_size 50m;
}

Adjust the timeout and body size to your actual workflows. Better still, design webhooks to respond immediately (see the Cloudflare section next) so proxy timeouts stop being a factor at all.

If you would rather never touch an Nginx config, this whole class of problem is exactly what managed hosting removes. On Hosto, every n8n instance runs on a dedicated VM with the reverse proxy, TLS, and WEBHOOK_URL configured correctly out of the box. Webhooks just work, from $9/mo billed annually.

Problem 4: Cloudflare is eating your webhooks

Symptom: Webhooks work fine when you test directly, but automated senders intermittently get 5xx errors, Cloudflare error pages, or timeouts, especially on workflows that take a while to finish.

Cause: If your n8n domain sits behind Cloudflare's proxy (the orange cloud), two things can go wrong:

  1. Timeouts. Cloudflare cuts off responses that take too long, roughly 100 seconds on standard plans. If your Webhook node is set to respond only when the workflow finishes, any long execution gets killed at the edge and the sender sees a failure, even though n8n completed the work.
  2. Bot challenges. Cloudflare's security features can challenge or block automated POST requests. A webhook sender cannot solve a browser challenge, so the request dies before reaching n8n.

Fix: Pick one (or combine them):

  • Respond immediately. In the Webhook node's response settings, choose the immediate-response mode instead of waiting for the workflow to finish. The sender gets an instant 200 and the workflow continues in the background. This is best practice regardless of Cloudflare. Most webhook providers expect a fast acknowledgment.
  • Bypass Cloudflare for the webhook hostname. Set the DNS record for your n8n subdomain to "DNS only" (gray cloud) so traffic goes straight to your server.
  • Allowlist the calling service. Create a WAF/firewall rule that skips challenges for the sender's IP ranges or for your webhook path.

Problem 5: HTTP method mismatch or path typo

Symptom: The sender gets a 404 (or a "method not allowed" style error), the workflow is definitely active, and the URL looks right at a glance.

Cause: Two small-but-deadly details:

  • Method mismatch. The Webhook node defaults to GET. Nearly every real-world webhook provider sends POST. If the node is listening for GET and Stripe POSTs to it, n8n rejects the request.
  • Path problems. A typo in the path (or the same path reused across two workflows) means requests either miss entirely or land somewhere you didn't intend.

Fix:

  1. Open the Webhook node and set HTTP Method to match what the sender actually uses (almost always POST).
  2. Compare the path in the node against the URL configured in the external service, character by character.
  3. Make sure no other workflow claims the same path. Give each webhook a unique, descriptive path.

A quick sanity test from your terminal:

curl -X POST https://n8n.yourdomain.com/webhook/my-path \
  -H "Content-Type: application/json" \
  -d '{"test": true}'

If curl succeeds but the real service fails, the problem is on the sender's side (wrong URL registered, or Cloudflare, see above).

Problem 6: You migrated servers and old webhook registrations still point at the old URL

Symptom: Everything worked before you moved n8n to a new host or changed domains. Now workflows with trigger nodes like Telegram simply never fire. No errors anywhere.

Cause: Nodes that manage their own webhooks (Telegram Trigger, and other app triggers) registered a callback URL with the third-party service at activation time. That registration lives on the third party's side. Move your n8n instance, and Telegram keeps sending updates to the old, dead URL forever. The same applies to webhooks you registered manually in dashboards like Stripe's.

Fix:

  1. Set WEBHOOK_URL to the new public URL (Problem 2).
  2. Deactivate and reactivate each affected workflow. For nodes that manage their own webhooks, reactivation re-registers the webhook with the new URL automatically.
  3. For manually registered webhooks (Stripe dashboard, GitHub repo settings, custom apps), update the endpoint URL by hand. n8n cannot do it for you.

Server migrations are a common moment to reassess your setup; if you are weighing options, see our breakdown of n8n Cloud vs self-hosted costs, or let a managed provider like Hosto handle the migration details for you.

Problem 7: Testing on localhost (external services can't reach you)

Symptom: n8n runs on your laptop at http://localhost:5678, and no external service ever triggers your webhook.

Cause: localhost is only reachable from your own machine. Stripe's servers cannot connect to your laptop; there is no route.

Fix: Expose your local instance through a tunnel. n8n ships a built-in tunnel mode for exactly this:

n8n start --tunnel

This gives you a temporary public URL that forwards to your local instance. Use it for development only, never in production. The tunnel routes your traffic through a shared external service and is not designed for reliability or security at production scale. When you are ready for real traffic, deploy to a server with a proper domain and TLS.

FAQ

Why does my n8n webhook work in test mode but not in production?

The test URL and production URL are separate endpoints with separate lifecycles. The test URL only listens while you actively click "Listen for test event" in the editor; the production URL only exists once the workflow is activated. If production calls fail, confirm the workflow toggle is set to Active and that the external service is calling the /webhook/ URL, not /webhook-test/.

What should WEBHOOK_URL be set to?

Set it to the full public HTTPS URL where your n8n instance is reachable, such as https://n8n.yourdomain.com/. Without it, n8n behind a reverse proxy or tunnel generates webhook URLs from its internal host and port, producing localhost-style URLs that external services can never reach.

How do I stop long-running workflows from timing out webhook senders?

Configure the Webhook node to respond immediately instead of waiting for the workflow to finish. The sender gets an instant acknowledgment while the workflow keeps running. This sidesteps reverse proxy timeouts and Cloudflare's ~100-second limit, and it matches what most webhook providers expect.

Do I need to re-register webhooks after changing my n8n domain?

Yes. Third-party services keep sending to whatever URL was registered at the time. Update WEBHOOK_URL, then deactivate and reactivate workflows so nodes that manage their own webhooks (like the Telegram Trigger) re-register automatically. Webhooks you configured manually in external dashboards must be updated there by hand.

Host it without the ops.

WordPress, WooCommerce, static sites, and dedicated n8n VMs. Same price at renewal, live in minutes.