# Fix n8n "webhook is not registered" 404s

Diagnose n8n webhook 404s from the "not registered" error body: classify test-vs-production URL lifecycle, workflow activation state, HTTP method/path mismatch, duplicate-path conflicts, and in-memory registration desync, with the matching fix for each (re-listen, re-activate, deactivate/activate cycle, container restart, support escalation).

Exact reference: {"kind":"skill_version","skill_id":"skl_bcOIcDFgcpfOykHmcVRngg","version_id":"skv_YxCk2sx9B7axW6olPrPhwQ"}

Applicability: [{"constraint":">=1.0, self-hosted and n8n Cloud","technology":"n8n","version_scheme":"semver"}]

# Fix n8n "webhook is not registered" 404s

Use this when an external caller gets a 404 with a body like:

```json
{"code":404,"message":"The requested webhook \"POST my-path\" is not registered.","hint":"The workflow must be active for a production URL to run successfully..."}
```

The message means n8n's router has no in-memory route for that method + path — the
request never reached a workflow. Do not change the workflow logic; the problem is
registration, activation state, or which URL the caller is using. Classify FIRST
from the observable evidence, then apply the matching fix.

## 1. Read the URL: test (`/webhook-test/`) vs production (`/webhook/`)

n8n registers two different endpoints for every Webhook node. They have completely
different lifecycles:

- **Test URL** (`https://example.com/webhook-test/[path]`): live only while the workflow
  editor has "Listen for Test Event" actively waiting on that node, and it fires
  **exactly once** — the second call gets a 404 even if nothing changed.
- **Production URL** (`https://example.com/webhook/[path]`): live only while the
  workflow is **active** (toggle ON and saved). Editing or testing in the editor
  does nothing to it.

Failure mode 1 — "it worked in testing, then 404 in production": the caller is
still hitting the test URL. Switch the caller to the production URL. Note the UI
quirk: the Webhook node dialog always opens on the Test URL tab even when the
workflow is active — that is display-only and does not mean production is broken.

Failure mode 2 — "the first test call worked, the second 404s": that is the
test listener being consumed. Click "Listen for Test Event" again for each test
call; do not diagnose this as a registration bug.

## 2. Confirm the workflow is really active

Production routes are registered when the workflow is activated, not when it is
saved. The toggle in the editor shows the saved state; a workflow saved as
inactive while the editor showed it "green" is a classic source of 404s.

- Toggle the workflow OFF, wait a few seconds, toggle ON, save, then retry the
  production URL.
- In the Executions list (not the canvas): if the call produced **zero**
  executions — not even failed ones — the request was rejected at the router,
  which confirms registration/activation rather than a node error. This is also a
  blind spot: webhook 404s leave no trace in n8n, so monitor them from the
  caller's side.

## 3. Check the method and path the caller is actually using

Registration is per HTTP method plus path. A caller sending GET to a Webhook node
configured for POST gets "not registered", not a method error.

- Compare the method in the error message (`"POST my-path"`) with the Webhook
  node's HTTP Method setting.
- Compare the full path segment-by-segment with the production URL shown in the
  node after activation. Duplicating a workflow or re-saving can regenerate the
  webhook path/ID, leaving the caller with a stale path.
- No two active workflows may share the same method + path. If another workflow
  uses the same path, deactivating one can deregister the route for the other.

## 4. Handle the registration desync: active in the DB, missing in memory

The known hard case: the workflow is active, the URL and method are correct, and
the caller still gets `not registered`. n8n keeps webhook routes in memory; the
in-memory table can fall out of sync with the database (seen after API-driven
activate calls, database permission resets, and on n8n Cloud tenant routing
issues). Evidence: `POST /rest/workflows/{id}/activate` returns 200 with
`"active": true`, the DB row is active, but `POST /webhook/{path}` still 404s.

Apply these in order:

1. `POST /rest/workflows/{id}/deactivate`, then `POST /rest/workflows/{id}/activate`
   — this forces the in-memory state to rebuild. Retry the webhook.
2. If that fails, restart the n8n container (`docker restart n8n`) — webhook
   registration runs at container startup, so a restart re-registers every
   active route.
3. If it still fails on n8n Cloud, this is tenant-level routing desync: contact
   n8n support and describe it as a workspace routing issue where production
   webhooks return 404 despite the workflow being active — they rebuild the
   routing table manually.

## 5. Checklist

1. Caller URL test vs production — match the lifecycle you need.
2. Workflow toggled active and saved (off/on cycle to be sure).
3. Method and path match the node's settings exactly; no stale or duplicated path.
4. Desync: deactivate/reactivate via API, then container restart, then support.
5. Zero executions in the list = router rejection; fix registration, not the flow.


## Supporting basis and limitations

Built from recurring community.n8n.io threads on production webhook 404s (test-vs-production URL lifecycle, UI defaulting to the Test URL tab, workflow activation as the real enabler) and GitHub issue n8n-io/n8n#34038 documenting the activate-API registration desync with the deactivate/reactivate and container-restart workarounds.

## Change and rationale

New skill: diagnose and fix n8n webhook 404 "not registered" errors via a registration/activation classification.

Webhook 404s are one of the most asked-about n8n issues and the default instinct is to edit workflow logic, which can never help: the request is rejected at the router before any workflow runs. This skill adds a decision procedure that classifies the failure from the URL, activation state, and method/path evidence before prescribing the fix, including the hard registration-desync case where the DB says active but the in-memory route is missing.
