google-gemini/gemini-cli · error · OAuthSecurityError
Failed to resolve hostname "${hostname}" for OAuth endpoint
Error message
Failed to resolve hostname "${hostname}" for OAuth endpoint "${resolvedUrl}". What it means
For non-loopback hosts, the library performs DNS resolution (lookup with { all: true }) as an SSRF/DNS-rebinding defense, and the lookup returned no addresses (empty array). The hostname is syntactically fine but resolves to nothing at validation time.
Source
Thrown at packages/core/src/mcp/oauth-utils.ts:139
throw new OAuthSecurityError(
`Loopback OAuth endpoint "${resolvedUrl}" is not allowed for remote MCP servers.`,
);
}
return parsed.toString();
}
// Non-loopback host: check literal IP
if (isAddressPrivate(hostname)) {
throw new OAuthSecurityError(
`OAuth endpoint "${resolvedUrl}" points to private or reserved IP address which is blocked.`,
);
}
// Asynchronous DNS resolution to prevent DNS rebinding / SSRF
try {
const addresses = await lookup(hostname, { all: true });
if (!addresses || addresses.length === 0) {
throw new OAuthSecurityError(
`Failed to resolve hostname "${hostname}" for OAuth endpoint "${resolvedUrl}".`,
);
}
for (const addr of addresses) {
if (isAddressPrivate(addr.address)) {
throw new OAuthSecurityError(
`OAuth endpoint "${resolvedUrl}" resolves to private network address "${addr.address}" which is blocked.`,
);
}
}
} catch (error) {
if (error instanceof OAuthSecurityError) {
throw error;
}
throw new OAuthSecurityError(
`DNS lookup failed for OAuth endpoint host "${hostname}": ${getErrorMessage(error)}`,
);View on GitHub (pinned to 3c311beac2)
Solutions
- Verify the hostname resolves from this environment: 'nslookup <hostname>' or 'node -e "require('dns').lookup(process.argv[1],{all:true},console.log)"'
- Fix typos in the configured OAuth endpoint hostname
- If using an internal DNS name, ensure the process's resolver can reach that DNS server (VPN, /etc/resolv.conf, Node's dns.setDefaultResultOrder caveats)
- Retry after DNS propagation or resolver recovery — this check is environment- and time-dependent
Example fix
// before
await validateOAuthEndpointUrl('https://auth.exmaple.com/authorize'); // typo'd domain, NXDOMAIN
// after
await validateOAuthEndpointUrl('https://auth.example.com/authorize'); Defensive patterns
Strategy: retry
Validate before calling
import { lookup } from 'node:dns/promises';
async function resolvesToAddresses(host: string): Promise<boolean> {
try { const a = await lookup(host, { all: true }); return a.length > 0; } catch { return false; }
}
if (!(await resolvesToAddresses(new URL(endpoint).hostname))) {
throw new Error(`Hostname does not resolve: ${endpoint}`);
} Type guard
async function isResolvableHost(host: string): Promise<boolean> {
try { return (await lookup(host, { all: true })).length > 0; } catch { return false; }
} Try / catch
try {
await validateOAuthEndpointUrl(endpoint);
} catch (e) {
if (e instanceof OAuthSecurityError && e.message.includes('Failed to resolve hostname')) {
// DNS returned no records: check typos/propagation/resolver, then retry after a delay
}
throw e;
} Prevention
- Smoke-test DNS resolution for OAuth hosts in deployment health checks
- Pin validated endpoint URLs in a cache so flaky DNS doesn't repeatedly break flows
- In CI, avoid real external hostnames — use local loopback endpoints with allowLoopback
When it happens
Trigger: validateOAuthEndpointUrl called with a hostname that DNS cannot resolve to any A/AAAA record — e.g. a typo'd domain, a not-yet-propagated record, an internal DNS name unknown to the resolver, or a temporarily failing resolver returning an empty result.
Common situations: Newly deployed OAuth hosts whose DNS records haven't propagated; corporate/internal DNS names resolved from outside the network; transient DNS flakiness in CI; air-gapped environments where public DNS is unavailable.
Related errors
- DNS lookup failed for OAuth endpoint host "${hostname}": ${g
- OAuth endpoint "${resolvedUrl}" resolves to private network
- Could not authenticate using metadata server application def
- Failed to resolve relative OAuth URL "${urlStr}" against bas
- Invalid OAuth endpoint protocol "${parsed.protocol}". Only H
AI-assisted analysis of google-gemini/gemini-cli@3c311beac2 (2026-08-27).
Data as JSON: /api/errors/b9a444fb03af55f6.
Report an issue: GitHub.