n8n-io/n8n · error · NodeOperationError

Default webhook url not set

Error message

Default webhook url not set

What it means

Thrown by the Chat Trigger's webhook handler (hostedChat setup GET) when ctx.getNodeWebhookUrl('default') returns a falsy value. The hosted chat page needs a public/known webhook URL to post messages to; without one it cannot render the chat.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/trigger/ChatTrigger/ChatTrigger.node.ts:888

		} catch (error) {
			if (error) {
				// Realm is scoped per webhook so browsers don't reuse cached credentials across chats sharing an origin
				const webhookId = ctx.getNode().webhookId;
				const realm = webhookId ? `Webhook ${webhookId}` : 'Webhook';
				res.writeHead((error as IDataObject).responseCode as number, {
					'www-authenticate': `Basic realm="${realm}"`,
				});
				res.end((error as IDataObject).message as string);
				return { noWebhookResponse: true };
			}
			throw error;
		}
		if (nodeMode === 'hostedChat') {
			// Show the chat on GET request
			if (webhookName === 'setup') {
				const webhookUrlRaw = ctx.getNodeWebhookUrl('default');
				if (!webhookUrlRaw) {
					throw new NodeOperationError(ctx.getNode(), 'Default webhook url not set');
				}

				const webhookUrl =
					mode === 'test' ? webhookUrlRaw.replace('/webhook', '/webhook-test') : webhookUrlRaw;
				const authentication = ctx.getNodeParameter('authentication') as
					| 'none'
					| 'basicAuth'
					| 'n8nUserAuth';
				const initialMessagesRaw = ctx.getNodeParameter('initialMessages', '');
				assertParamIsString('initialMessage', initialMessagesRaw, ctx.getNode());
				const instanceId = ctx.getInstanceId();

				const i18nConfig: Record<string, string> = {};
				const keys = ['getStarted', 'inputPlaceholder', 'subtitle', 'title'] as const;
				for (const key of keys) {
					if (options[key] !== undefined) {
						i18nConfig[key] = options[key];
					}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Set the WEBHOOK_URL (and if needed N8N_HOST, N8N_PORT, N8N_PROTOCOL) environment variable to the externally reachable base URL, then restart n8n.
  2. If behind a reverse proxy, configure N8N_EDITOR_BASE_URL and the proxy headers (X-Forwarded-*) so n8n computes the URL correctly.
  3. For local testing, set WEBHOOK_URL=http://localhost:5678/.
  4. Confirm the setting took effect by checking the instance settings after restart.

Example fix

# before: no WEBHOOK_URL set → getNodeWebhookUrl returns undefined → throws
# after (env):
export WEBHOOK_URL=https://n8n.example.com/
# then restart n8n.
Defensive patterns

Strategy: validation

Validate before calling

const url = ctx.getNodeWebhookUrl('default');
if (!url) throw new Error('Set WEBHOOK_URL env var so n8n knows its public webhook base');

Type guard

function webhookUrlIsConfigured(url: string | undefined): url is string {
  return typeof url === 'string' && url.length > 0;
}

Prevention

When it happens

Trigger: The n8n instance has no WEBHOOK_URL / N8N_WEBHOOK_URL environment variable set and cannot derive a URL (common in local/offline setups); the instance is behind a proxy that hasn't been configured so n8n cannot determine its own external URL.

Common situations: Running n8n locally without setting WEBHOOK_URL; fresh installs; Docker/behind-reverse-proxy setups missing the VITE/WEBHOOK URL env vars; toggling to production mode without configuring the public URL.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/2e59707e11ae448a. Report an issue: GitHub.