koala73/worldmonitor · error · McpProxySsrfError
serverUrl DNS resolution failed: ${message}
Error message
serverUrl DNS resolution failed: ${message} What it means
Thrown by assertServerUrlSafe when defaultResolveHostname (DoH A+AAAA against cloudflare-dns.com/dns-query, 3s timeout) raises — the DoH fetch returned non-2xx, the JSON body's Status was non-zero, or the fetch aborted/timed out. The underlying error message is interpolated so the caller can see why DNS failed. Surfaced as a McpProxySsrfError.
Source
Thrown at api/mcp-proxy.ts:168
]);
return records.flat();
}
async function assertServerUrlSafe(url) {
const hostname = url.hostname.toLowerCase();
if (BLOCKED_HOSTNAMES.has(hostname)) {
throw new McpProxySsrfError(`serverUrl hostname is blocked: ${hostname}`);
}
if (isBlockedResolvedAddress(hostname)) {
throwBlockedAddress(hostname);
}
let resolvedAddresses;
try {
resolvedAddresses = await defaultResolveHostname(hostname);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new McpProxySsrfError(`serverUrl DNS resolution failed: ${message}`);
}
if (!resolvedAddresses.length) {
throw new McpProxySsrfError('serverUrl DNS resolution returned no addresses');
}
const blocked = resolvedAddresses.find(isBlockedResolvedAddress);
if (blocked) {
throwBlockedAddress(blocked);
}
return { url, resolvedAddresses };
}
// Vercel Edge fetch does not expose a Node-style lookup/socket hook, so this
// proxy CANNOT pin the TLS connection to a previously vetted address. There is
// no way to guarantee that the IP we validated is the IP fetch() ultimately
// connects to; a DNS answer can change between our resolve and fetch's ownView on GitHub (pinned to ffec79ac33)
Solutions
- Retry the proxy call after a short delay — DoH failures are typically transient.
- Confirm the serverUrl hostname resolves normally via `dig`/`host`.
- Check Cloudflare status for DoH incidents.
- Verify Edge egress to https://cloudflare-dns.com is not blocked by a deployment-level egress policy.
Example fix
// before
proxy({ serverUrl: 'https://mcp.good-but-doh-failed.example.com/mcp' })
// -> 'serverUrl DNS resolution failed: DNS A lookup failed: HTTP 503'
// after (retry once on a transient DoH failure)
await retry(() => proxy({ serverUrl: 'https://mcp.example.com/mcp' }), { tries: 2 }) Defensive patterns
Strategy: retry
Validate before calling
async function dohReachable(): Promise<boolean> {
try {
const r = await fetch('https://cloudflare-dns.com/dns-query?name=example.com&type=A', {
headers: { Accept: 'application/dns-json' },
signal: AbortSignal.timeout(1500),
});
return r.ok && (await r.json()).Status === 0;
} catch { return false; }
} Try / catch
async function proxyWithRetry(payload, attempts = 2) {
for (let i = 0; i < attempts; i++) {
try { return await runProxy(payload); }
catch (err) {
if (err.name === 'McpProxySsrfError' && err.message.startsWith('serverUrl DNS resolution failed:') && i < attempts - 1) {
await new Promise(r => setTimeout(r, 500)); continue;
}
throw err;
}
}
} Prevention
- Treat DNS-resolution-failed as transient — retry with backoff.
- Confirm Edge egress to cloudflare-dns.com is allowed by any deployment egress policy.
- Distinguish DoH-outage (retry) from blocked-host (do not retry) by inspecting the wrapped message.
When it happens
Trigger: POST /api/mcp-proxy with a serverUrl whose hostname the DoH resolver could not resolve — Cloudflare DoH endpoint returned 5xx, the 3s AbortSignal fired, or Status != 0 in the response body.
Common situations: Transient Cloudflare DoH outage; a hostname with a pathological CNAME chain timing out; Edge egress to cloudflare-dns.com blocked or degraded; rate-limiting from the DoH endpoint.
Understand the failure class
- DNS resolution errors: ENOTFOUND and getaddrinfo failures — how hostname lookups fail and how to debug them.
Related errors
- serverUrl DNS resolution returned no addresses
- Webhook URL DNS resolution failed: ${message}
- serverUrl host is not allowed
- serverUrl hostname is blocked: ${hostname}
- Webhook URL DNS resolution returned no addresses
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/d5dd50f418898a25.
Report an issue: GitHub.