musistudio/claude-code-router · error · Error
Remote manifest host resolved to a private or reserved addre
Error message
Remote manifest host resolved to a private or reserved address: ${address.address} What it means
After resolving the manifest host, every returned IP is checked with isPublicIpAddress; if any resolved address is private/reserved (RFC1918, loopback, link-local, etc.) this error fires. This defeats DNS-rebinding SSRF: a public-looking hostname that resolves to an internal IP is rejected.
Source
Thrown at packages/core/src/providers/manifest-service.ts:247
normalized.endsWith(".localhost") ||
normalized.endsWith(".home") ||
normalized.endsWith(".lan") ||
normalized.endsWith(".local") ||
normalized.endsWith(".internal")
) {
throw new Error(`${label} cannot target a local or internal host.`);
}
}
async function resolveSafeAddress(hostname: string): Promise<SafeAddress> {
const addresses = await lookup(hostname, { all: true, verbatim: true });
if (addresses.length === 0) {
throw new Error(`Could not resolve host: ${hostname}`);
}
for (const address of addresses) {
if (!isPublicIpAddress(address.address)) {
throw new Error(`Remote manifest host resolved to a private or reserved address: ${address.address}`);
}
}
const first = addresses[0];
return {
address: first.address,
family: first.family === 6 ? 6 : 4
};
}
function isPublicIpAddress(address: string): boolean {
const family = net.isIP(address);
if (family === 4) {
return isPublicIpv4(address);
}
if (family === 6) {
return isPublicIpv6(address);
}View on GitHub (pinned to 99f24806c6)
Solutions
- Use a host whose DNS returns only public addresses (remove internal A/AAAA records from the public zone)
- Avoid rebinding-friendly domains (nip.io etc.) in manifests
- For internal targets, use a local manifest rather than a remote one
- Check `dig +short <host>` for the full record set from the machine running the app
Defensive patterns
Strategy: validation
Validate before calling
import { lookup } from 'node:dns/promises';
import { isPublicIpAddress } from './ip';
const addrs = await lookup(hostname, { all: true });
if (addrs.some(a => !isPublicIpAddress(a.address))) throw new Error('non-public resolution'); Prevention
- Ensure public DNS zones contain only public A/AAAA records
- Avoid rebinding-style wildcard domains in manifests
When it happens
Trigger: A manifest host whose DNS A/AAAA records include 10.x, 192.168.x, 172.16-31.x, 127.x, 169.254.x, or other non-public ranges — including multi-record responses where only some records are private.
Common situations: Wildcard DNS (e.g. nip.io/sslip.io style) mapping to 127.0.0.1; a service with both public and internal A records; DNS rebinding services; split-horizon DNS returning the internal IP to your network.
Related errors
- Could not resolve host: ${hostname}
- ${identityIssue.message}
- ${label} cannot target a local or internal host.
- Claude App profiles do not support agent arguments.
- Artifact origin is not the configured CCR gateway.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/5fc527509420e2f9.
Report an issue: GitHub.