What We Learned
Self-hosted n8n with a single worker cannot call its own public webhook URL from within an executing workflow. The calling workflow occupies the worker; the callee webhook queues but never executes; the caller times out after 10 minutes. This is a textbook concurrency deadlock with no obvious error message — the failure looks like a connection timeout, not a resource exhaustion. The fix is a one-line URL change in the HTTP Request node: replace the external URL (https://hab.so1.io/webhook/atomiser) with the internal URL (http://localhost:5678/webhook/atomiser). n8n routes localhost calls differently from external calls, allowing concurrent execution even with a single worker configured.
Why It Matters
This pattern applies to any n8n deployment where one workflow orchestrates another on the same instance. The architecture is common — a “dispatcher” workflow that breaks work into chunks and triggers “worker” workflows. If the dispatcher waits for the worker’s response, and both use the public URL, it deadlocks every time. The rule: n8n workflows calling sibling workflows on the same instance must usehttp://localhost:{port}/webhook/{path} not the public URL.
Operational Implication
When debugging a FORGE execution that runs for exactly 10 minutes then fails atTrigger TOMMY: check the URL. If it contains the public hostname, change it to localhost. If the port is unknown, check what process is listening on 5678 on the n8n host (ss -tlnp | grep 5678).
For production deployments expecting blocks longer than 10 minutes, also increase the timeout on the HTTP Request node (options.timeout) beyond 600000ms, or switch to n8n’s native Execute Workflow node which avoids HTTP routing entirely.