modelcontextprotocol/servers · error · Error
Domain ${domain} is not in the allowed domains list.
Error message
Domain ${domain} is not in the allowed domains list. What it means
Thrown by `validateDataURI` when the `GZIP_ALLOWED_DOMAINS` env var is set (non-empty) and the http/https URL's hostname is neither an exact match nor a subdomain of any allowed domain. This is an SSRF-control allowlist; an empty env disables the check entirely.
Source
Thrown at src/everything/tools/gzip-file-as-resource.ts:157
if (
url.protocol !== "http:" &&
url.protocol !== "https:" &&
url.protocol !== "data:"
) {
throw new Error(
`Unsupported URL protocol for ${dataUri}. Only http, https, and data URLs are supported.`
);
}
if (
GZIP_ALLOWED_DOMAINS.length > 0 &&
(url.protocol === "http:" || url.protocol === "https:")
) {
const domain = url.hostname;
const domainAllowed = GZIP_ALLOWED_DOMAINS.some((allowedDomain) => {
return domain === allowedDomain || domain.endsWith(`.${allowedDomain}`);
});
if (!domainAllowed) {
throw new Error(`Domain ${domain} is not in the allowed domains list.`);
}
}
} catch (error) {
throw new Error(
`Error processing file ${dataUri}: ${
error instanceof Error ? error.message : String(error)
}`
);
}
return url;
}
/**
* Fetches data safely from a given URL while ensuring constraints on maximum byte size and timeout duration.
*
* @param {URL} url The URL to fetch data from.
* @param {Object} options An object containing options for the fetch operation.
* @param {number} options.maxBytes The maximum allowed size (in bytes) of the response. If the response exceeds this size, the operation will be aborted.View on GitHub (pinned to 76d64c822f)
Solutions
- Add the exact hostname (and any subdomain-bearing parent) to `GZIP_ALLOWED_DOMAINS`, e.g. `example.com,raw.githubusercontent.com`.
- Use a URL whose host is already in the allowlist or a subdomain of one.
- To disable domain filtering entirely, leave `GZIP_ALLOWED_DOMAINS` unset/empty (recognize the security trade-off).
Example fix
# before
GZIP_ALLOWED_DOMAINS=example.com
toolHandler({ data: 'https://raw.githubusercontent.com/x/y/z.md' })
# after
GZIP_ALLOWED_DOMAINS=example.com,raw.githubusercontent.com
toolHandler({ data: 'https://raw.githubusercontent.com/x/y/z.md' }) Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = (process.env.GZIP_ALLOWED_DOMAINS ?? '').split(',').map(d=>d.trim().toLowerCase()).filter(Boolean);
function domainAllowed(url: string): boolean {
if (ALLOWED.length === 0) return true;
const h = new URL(url).hostname.toLowerCase();
return ALLOWED.some(a => h === a || h.endsWith('.' + a));
}
if (!domainAllowed(args.data)) { /* surface error */ } Prevention
- Keep GZIP_ALLOWED_DOMAINS in sync with every domain you fetch from.
- List parent domains to cover subdomains (example.com covers www.example.com).
- Leaving the env empty disables the check — only do so in trusted environments.
When it happens
Trigger: Operator set `GZIP_ALLOWED_DOMAINS=example.com,github.com` and the tool is called with a URL whose host is e.g. `evil.com` or `notgithub.com` (which is not a subdomain match). The check uses exact hostname match or `.endsWith('.' + allowed)`.
Common situations: Misconfigured allowlist (forgot a domain), URL using a bare host vs `www.` variant that isn't covered, or a CDN/redirect domain not in the list. Note: only `endsWith("." + allowed)` — so `evil-example.com` is correctly rejected, but operators must list every domain they intend to permit.
Related errors
- Unsupported URL protocol for ${dataUri}. Only http, https, a
- Content-Length for ${url} exceeds max of ${maxBytes}: ${cont
- Response from ${url} exceeds ${maxBytes} bytes
- Invalid resourceType: ${args?.resourceType}. Must be ${RESOU
- Invalid resourceId: ${args?.resourceId}. Must be a finite po
AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12).
Data as JSON: /api/errors/1cd16567103d87a4.
Report an issue: GitHub.