diegosouzapw/OmniRoute · error · Error
Subscription host resolves to a blocked (internal) address
Error message
Subscription host resolves to a blocked (internal) address
What it means
Error "Subscription host resolves to a blocked (internal) address" thrown in diegosouzapw/OmniRoute.
Source
Thrown at src/lib/proxySubscription/subscriptionService.ts:312
* blocked UNCONDITIONALLY regardless of that flag.
*/
async function assertSafeFetchTarget(url: string): Promise<void> {
const guardOpts: FetchGuardOptions = { allowLocal: areLocalProviderUrlsAllowed() };
if (!isSubscriptionFetchUrlAllowed(url, guardOpts)) {
throw new Error("Subscription URL is not allowed (scheme or host blocked)");
}
const host = new URL(url).hostname.toLowerCase();
const bare = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
if (!isIpLiteral(bare)) {
// Hostname: resolve ALL records and refuse if ANY address is internal
// (fail closed). A hostname can resolve to multiple records; checking only
// the first would let an internal IP slip through if a public record also
// exists. `lookup(..., { all: true })` returns every A/AAAA record.
try {
const dns = await import("node:dns");
const addrs = await dns.promises.lookup(bare, { all: true });
if (isAnyResolvedAddressBlocked(addrs, guardOpts)) {
throw new Error("Subscription host resolves to a blocked (internal) address");
}
} catch (e) {
if (e instanceof Error && e.message.includes("blocked")) throw e;
throw new Error(`Subscription host resolution failed: ${e instanceof Error ? e.message : e}`);
}
}
}
/**
* Single fetch attempt: SSRF-validate the target, fetch with manual redirect
* handling, and re-validate any redirect target. Throws on non-2xx or a
* blocked target. Each attempt owns its own timeout so a retry after a fast
* failure isn't killed by the previous attempt's timer.
*/
async function doSafeFetch(url: string, headers: Record<string, string>): Promise<string> {
await assertSafeFetchTarget(url);
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), SUBSCRIPTION_FETCH_TIMEOUT_MS);View on GitHub (pinned to a179ffed5b)
When it happens
Trigger: Thrown at src/lib/proxySubscription/subscriptionService.ts:312 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25).
Data as JSON: /api/errors/9fe228beeaad5fa2.
Report an issue: GitHub.