different-ai/openwork · error · LocalManagedMcpPrivateUrlError
the address is private or reserved
Error message
the address is private or reserved
What it means
After confirming HTTPS, assertLocalManagedMcpUrl resolves the hostname and rejects addresses that are private, loopback, link-local, or otherwise reserved (checked via isLocalManagedMcpPrivateAddress). This prevents SSRF-style egress to internal infrastructure from the managed MCP runtime.
Source
Thrown at apps/server/src/local-managed-mcp-url-guard.ts:178
}
const first = addresses[0];
callback(null, first.address, first.family);
}, (error: unknown) => {
callback(error instanceof Error ? error : new Error("Managed MCP hostname lookup failed."), []);
});
};
}
export async function assertLocalManagedMcpUrl(rawUrl: string): Promise<void> {
const url = parseHttpUrl(rawUrl);
if (allowPrivateUrls()) return;
if (url.protocol !== "https:") {
throw new LocalManagedMcpPrivateUrlError(rawUrl, "managed MCP egress requires HTTPS");
}
const hostname = url.hostname.replace(/^\[|\]$/g, "");
if (isIP(hostname)) {
if (isLocalManagedMcpPrivateAddress(hostname)) {
throw new LocalManagedMcpPrivateUrlError(rawUrl, "the address is private or reserved");
}
return;
}
let addresses: LookupAddress[];
try {
addresses = await resolveAddresses(hostname, { all: true, verbatim: true });
} catch {
throw new LocalManagedMcpPrivateUrlError(rawUrl, "the hostname does not resolve");
}
validateResolvedAddresses(hostname, addresses);
}
type FetchLike = (url: string | URL, init?: RequestInit) => Promise<Response>;
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
const guardedDispatcher = new Agent({
connect: {
lookup: createLocalManagedMcpPublicLookup(),
// Node's 250 ms family-attempt default is too aggressive for otherwiseView on GitHub (pinned to 2b7df46e8a)
Solutions
- Use the public DNS hostname of the MCP server instead of a private IP
- If the connection is intentionally local/internal, enable the allowPrivateUrls() switch for that environment
- Check for typos in the configured IP (e.g. 10.0.0.1 vs a public address)
- Verify the server publishes a public endpoint reachable over HTTPS
Example fix
// before
await createLocalManagedMcpConnection({ url: "https://192.168.1.10/mcp" });
// after
await createLocalManagedMcpConnection({ url: "https://mcp.internal-gateway.example.com/mcp" }); Defensive patterns
Strategy: validation
Validate before calling
import { isIP } from "node:net";
const host = new URL(rawUrl).hostname.replace(/^\[|\]$/g, "");
if (isIP(host) && (host === "127.0.0.1" || host.startsWith("10.") || host.startsWith("192.168.") || host === "::1")) {
throw new Error(`Refusing private address for managed MCP: ${host}`);
} Type guard
function isPublicLiteralIp(hostname: string): boolean {
return isIP(hostname) === 0 || !isLocalManagedMcpPrivateAddress(hostname);
} Try / catch
try {
await createLocalManagedMcpConnection({ url });
} catch (error) {
if (error instanceof LocalManagedMcpPrivateUrlError && error.message === "the address is private or reserved") {
// prompt user to provide the public hostname of the MCP server
}
throw error;
} Prevention
- Configure servers by public DNS name, never by internal IP
- Never hardcode loopback or RFC1918 addresses in production config
- Enable private-URL allowance only in explicitly local/dev environments
- Document which addresses are considered private when planning internal deployments
When it happens
Trigger: Calling createLocalManagedMcpConnection or withRemoteClient with a URL whose hostname is a literal IP (e.g. 127.0.0.1, 10.x.x.x, 192.168.x.x, ::1) that isLocalManagedMcpPrivateAddress classifies as private/reserved, while private URLs are not allowed.
Common situations: Configuring an MCP server by internal cluster IP instead of its public hostname; pointing at 127.0.0.1 for a locally running server; IPv6 literals like [::1] (brackets are stripped before the check); Docker-internal addresses like 172.17.x.x.
Related errors
- Attachment hostname ${hostname} resolved to a private or res
- the hostname resolves to a private or reserved address (${ad
- managed MCP egress requires HTTPS
- MCP_URL_BLOCKED
- External URL protocol "${parsed.protocol}" is not allowed.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/06ac11cbed05f13d.
Report an issue: GitHub.