n8n-io/n8n · error · Error

Invalid URL in allow list: "${entry}" - ${error instanceof E

Error message

Invalid URL in allow list: "${entry}" - ${error instanceof Error ? error.message : error}

What it means

Thrown by the Guardrails URL allow-list check when constructing `new URL(entry)` for an allow-list entry raises an exception. Each allow-list entry must be a URL string parseable by the WHATWG URL parser; anything that fails parsing is treated as an invalid configuration value and aborts the check rather than being silently ignored.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/Guardrails/actions/checks/urls.ts:218

	for (const allowedEntry of allowList) {
		const entry = allowedEntry.toLowerCase().trim();

		// Handle full URLs with specific paths
		if (entry.includes('://')) {
			try {
				const allowedUrl = new URL(entry);
				const allowedHost = allowedUrl.hostname?.toLowerCase();
				const allowedPath = allowedUrl.pathname;

				if (urlHost === allowedHost) {
					// Check if the URL path starts with the allowed path
					if (!allowedPath || allowedPath === '/' || parsedUrl.pathname.startsWith(allowedPath)) {
						return true;
					}
				}
			} catch (error) {
				throw new Error(
					`Invalid URL in allow list: "${entry}" - ${error instanceof Error ? error.message : error}`,
				);
			}
			continue;
		}

		// Handle IP addresses and CIDR blocks
		try {
			// Basic IP pattern check
			if (/^\d+\.\d+\.\d+\.\d+/.test(entry.split('/')[0])) {
				if (entry === urlHost) {
					return true;
				}
				// Proper CIDR validation
				if (entry.includes('/') && urlHost.match(/^\d+\.\d+\.\d+\.\d+$/)) {
					const [network, prefixStr] = entry.split('/');
					const prefix = parseInt(prefixStr);

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Give every URL allow-list entry a full form including scheme, e.g. "https://example.com" rather than "example.com".
  2. Trim whitespace and remove smart quotes / invisible characters from pasted entries.
  3. Move pure IP/CIDR entries to the field meant for them so they are not parsed as URLs, or confirm they only reach the IP/CIDR branch.
  4. Validate the whole allow list with `new URL()` in a scratch script before saving the node parameters.

Example fix

// before
const allowList = ['example.com', 'https://api.example.com'];
// after
const allowList = ['https://example.com', 'https://api.example.com'];
Defensive patterns

Strategy: validation

Validate before calling

function isValidUrlEntry(entry) {
  try { new URL(entry); return true; } catch { return false; }
}
const clean = allowList.filter((e) => typeof e === 'string' && e.trim() && isValidUrlEntry(e.trim()));

Type guard

function isParseableUrl(entry) { try { new URL(entry); return true; } catch { return false; } }

Try / catch

try {
  new URL(entry);
} catch (e) {
  // skip or collect invalid entries instead of aborting the whole check
}

Prevention

When it happens

Trigger: The allow-list is iterated and for each entry the code attempts `new URL(entry)` inside a try/catch. The catch re-throws a descriptive Error only when urlHost matches or the entry is meant to be evaluated as a URL. Triggers: an entry without a scheme (e.g. "example.com"), a malformed string (e.g. "ht!tp://x"), a stray protocol-relative "//host", or a non-URL value placed in a URL allow-list field.

Common situations: Users pasting bare hostnames instead of full URLs into the Guardrails URL allow list; copy-pasting entries with trailing spaces or smart quotes; mixing CIDR/IP entries (handled by a later branch) with URL entries and forgetting the URL branch still runs `new URL` on them when urlHost coincidentally matches.

Related errors


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