error fix
n8n Webhook Not Working: Test vs Production URLs and Reverse Proxy Fixes
Webhook problems usually come from using the wrong test or production URL, not activating or publishing the workflow, or exposing a self-hosted instance without the correct public webhook base URL.
Match your incident first
Start with the symptom you can prove
Test URL works, production URL returns 404
First check: Open the Webhook node and compare the active or published production URL with the external app callback URL.
Wrong fix to avoid: Do not rebuild the whole workflow before proving whether the active production endpoint exists.
Verify: Activate or publish the workflow, send a POST to the production URL, and confirm one new production execution appears.
Production URL shows localhost, container hostname, or http instead of public HTTPS
First check: Check the public URL shown in n8n and compare it with WEBHOOK_URL and reverse proxy forwarded headers.
Wrong fix to avoid: Do not paste the internal Docker service name into external SaaS callback settings.
Verify: The Webhook node displays the public HTTPS domain and an external curl reaches n8n without redirect loops.
External app times out but n8n logs show no execution
First check: Run an external curl smoke test and inspect reverse proxy access logs for the same timestamp.
Wrong fix to avoid: Do not rotate credentials when the request never reaches n8n.
Verify: Proxy access log and n8n execution log both show the same request.
- Use when
- self-hosted, n8n Cloud, webhooks
- First check
- Confirm the workflow is active or published and the caller is using the production webhook URL.
- Time to check
- 5-10 minutes
- Next step
- Match the symptom, then run the verification checks.
Independent third-party notes. n8n is a trademark of its owner and is referenced only for compatibility and troubleshooting context.
Quick Answer
Webhook problems usually come from using the wrong test or production URL, not activating or publishing the workflow, or exposing a self-hosted instance without the correct public webhook base URL.
Does this match your symptom?
Webhook is not reaching production
A test webhook works in the editor, but the production URL returns 404, uses the wrong method, or never creates an execution.
First check: Confirm the workflow is active or published and the caller is using the production webhook URL.
Problem Pattern
The user has a webhook that appears correct inside n8n but fails when called by an external app, usually because the wrong URL mode, activation or publishing state, public base URL, or proxy route is being used.
Version awareness
Last reviewed 2026-06-19
Key Facts
- Two URL modes
- The Webhook node has test and production URLs.
- Test URL
- Useful while the editor is listening for a manual test call; n8n's test listener is temporary.
- Production URL
- Used by active or published workflows for real incoming requests; production executions are checked from execution history, not the editor's waiting state.
- Self-hosting variable
- WEBHOOK_URL sets the public base URL for generated webhook URLs.
Production Diagnostic Matrix
Turn checks into a brief| Exact symptom or log | Likely cause | First check | Wrong fix to avoid | Verification |
|---|---|---|---|---|
| Test URL works, production URL returns 404 | Workflow is not active or published, caller is using the test URL, or the production path was changed after activation. | Open the Webhook node and compare the active or published production URL with the external app callback URL. | Do not rebuild the whole workflow before proving whether the active production endpoint exists. | Activate or publish the workflow, send a POST to the production URL, and confirm one new production execution appears. |
| Production URL shows localhost, container hostname, or http instead of public HTTPS | WEBHOOK_URL, N8N_HOST, N8N_PROTOCOL, or proxy headers do not match the public domain. | Check the public URL shown in n8n and compare it with WEBHOOK_URL and reverse proxy forwarded headers. | Do not paste the internal Docker service name into external SaaS callback settings. | The Webhook node displays the public HTTPS domain and an external curl reaches n8n without redirect loops. |
| External app times out but n8n logs show no execution | DNS, firewall, Cloudflare, reverse proxy, or path routing blocks the request before it reaches n8n. | Run an external curl smoke test and inspect reverse proxy access logs for the same timestamp. | Do not rotate credentials when the request never reaches n8n. | Proxy access log and n8n execution log both show the same request. |
| Provider shows 301, 308, 405, or missing body before n8n creates an execution | The webhook URL is hitting a canonical host, http-to-https, slash, or proxy redirect before it reaches the n8n production webhook route. | Run curl without following redirects and compare the Location header with the exact production URL saved in the provider. | Do not rely on curl -L alone; it can hide a redirect that the provider handles differently. | The provider calls the final HTTPS production webhook URL directly and n8n creates one execution with the expected method and body. |
| Workflow receives payload but caller gets wrong response or hangs | Respond to Webhook is missing, configured for the wrong response mode, or waits for a branch that does not finish. | Check the Webhook node response mode and the Respond to Webhook node path. | Do not add arbitrary Wait nodes to hide timeout behavior. | Caller receives the intended status code and body within the provider timeout window. |
| Production call succeeds but no payload appears in the editor canvas | The caller used the production URL, where data is reviewed through executions instead of the editor's test listener. | Open the Executions tab for the workflow and inspect the production execution created at the request timestamp. | Do not switch the third-party app back to the test URL just to make the editor show data. | One production execution exists with the expected method, headers, and non-sensitive payload fields. |
| Webhook path works internally but fails through reverse proxy | Proxy location, base path, body size, TLS termination, or forwarded proto/host headers are wrong. | Compare direct container access with the public reverse proxy route and check forwarded headers. | Do not disable HTTPS verification as a proxy troubleshooting shortcut. | Public HTTPS request preserves method, path, body, and host all the way to n8n. |
Still blocked after these checks?
Use the brief to decide whether to keep fixing this setup, move the workload to n8n Cloud, or rebuild the self-hosted path on cleaner infrastructure.
Recommended Steps
- Check whether the external service is calling the test URL or production URL.
- Activate or publish the workflow before using the production webhook URL.
- For self-hosted instances, set WEBHOOK_URL to the public domain that receives webhook traffic.
- Confirm any reverse proxy forwards the webhook path to n8n.
- Send a small test request and inspect the production execution result.
Verification
- The generated webhook URL uses the public domain.
- A request from outside the server reaches the workflow.
- The workflow execution history shows the incoming payload.
First Commands / Checks
curl -i -X POST https://automation.example.com/webhook/example-path \
-H "content-type: application/json" \
-d '{"smokeTest":true}' curl -i --max-redirs 0 -X POST https://automation.example.com/webhook/example-path \
-H "content-type: application/json" \
-d '{"smokeTest":true}' docker compose ps docker compose logs n8n --tail=100 docker compose exec n8n printenv WEBHOOK_URL N8N_HOST N8N_PROTOCOL N8N_EDITOR_BASE_URL Warnings
- A test webhook URL will not behave like a long-running production endpoint; n8n's test listener is temporary.
- If WEBHOOK_URL points to localhost, external services cannot reach the instance.
- A successful production webhook call may not appear in the editor UI; verify it in the workflow execution history.
- Webhook providers may not retry or preserve POST bodies across redirects; use the final HTTPS production URL directly.
Best For
- Webhook nodes that work in the editor but fail from an external service.
- Self-hosted deployments where generated webhook URLs show the wrong domain.
- Production workflows that receive no execution even though the external app says it sent a request.
Not For
- General HTTP Request node failures where n8n is the caller rather than the receiver.
- Credential errors inside downstream app nodes.
- Workflows that are intentionally inactive.
Common Mistakes
- Putting a test webhook URL into a production third-party integration.
- Forgetting to activate or publish the workflow before using the production webhook URL.
- Thinking the production webhook failed only because the payload does not appear in the editor's test listener.
- Leaving WEBHOOK_URL unset on a reverse-proxied self-hosted instance.
- Testing from the server itself but never testing from outside the network.
- Accepting a 301 or 308 redirect in curl -L without checking whether the external provider follows it with the same method and body.
Examples
Expected:
https://automation.example.com/webhook/customer-created
Suspicious:
http://localhost:5678/webhook/customer-created
http://n8n:5678/webhook/customer-created curl -X POST https://automation.example.com/webhook/customer-created \
-H 'Content-Type: application/json' \
-d '{"test":true,"source":"manual-smoke-test"}' FAQ
Why does the test webhook work but production does not?
The production webhook usually requires the workflow to be active or published, while the test URL is meant for editor-time testing and only listens temporarily.
Why did the production webhook run but no data appeared in the editor?
Production webhook data is checked from workflow execution history. The editor's waiting state is for test calls, so use the Executions tab or execution log when validating production calls.
Why does the external app get a timeout?
Common causes are a private localhost URL, reverse proxy routing failure, missing HTTPS, blocked firewall, or a workflow that takes too long before responding.
Should I use Respond to Webhook?
Use it when the caller needs a specific response body, status code, or timing behavior. Otherwise the default response behavior may be enough.