decolua/9router · warning
[ProxyFetch] Proxy failed, falling back to direct bypass: ${
Error message
[ProxyFetch] Proxy failed, falling back to direct bypass: ${proxyError.message} What it means
When a proxy is configured for a request, proxyAwareFetch attempts the fetch through the proxy dispatcher (undici ProxyAgent). If the proxied attempt throws and strictProxy is not enabled, it logs this warning and retries directly, resolving the real IP via DNS to bypass potential DNS spoofing. Only when strictProxy=true does the proxy failure propagate as a thrown error.
Source
Thrown at open-sse/utils/proxyFetch.js:324
return originalFetch(vercelRelayUrl, { ...options, headers: relayHeaders });
}
const connectionProxyUrl = resolveConnectionProxyUrl(targetUrl, proxyOptions);
const envProxyUrl = connectionProxyUrl ? null : normalizeProxyUrl(getEnvProxyUrl(targetUrl));
const proxyUrl = connectionProxyUrl || envProxyUrl;
// MITM DNS bypass: for known MITM-intercepted hosts, resolve real IP to avoid DNS spoof
if (shouldBypassMitmDns(targetUrl)) {
if (proxyUrl) {
// Proxy resolves DNS externally (not affected by /etc/hosts) — use proxy directly
try {
const dispatcher = await getDispatcher(proxyUrl);
return await originalFetch(url, { ...options, dispatcher });
} catch (proxyError) {
if (proxyOptions?.strictProxy === true) {
throw new Error(`[ProxyFetch] Proxy required but failed (strictProxy=true): ${proxyError.message}`);
}
console.warn(`[ProxyFetch] Proxy failed, falling back to direct bypass: ${proxyError.message}`);
}
}
// No proxy — manually resolve real IP to bypass DNS spoof
try {
const parsedUrl = new URL(targetUrl);
const realIP = await resolveRealIP(parsedUrl.hostname);
if (realIP) return await createBypassRequest(parsedUrl, realIP, options);
} catch (error) {
console.warn(`[ProxyFetch] MITM bypass failed: ${error.message}`);
}
}
if (proxyUrl) {
try {
const dispatcher = await getDispatcher(proxyUrl);
return await originalFetch(url, { ...options, dispatcher });
} catch (proxyError) {
// If strictProxy is enabled, fail hard instead of falling back to directView on GitHub (pinned to 90b52e06ff)
Solutions
- Verify the proxy URL (protocol, host, port, credentials) in proxy settings and test it with curl
- If traffic MUST go through the proxy, set strictProxy=true so failures throw instead of leaking direct requests
- Check that the proxy is running and reachable from the gateway host
- Confirm proxy auth credentials are included in the proxy URL (http://user:pass@host:port)
- If direct fallback is acceptable, treat this warning as informational and fix the proxy at leisure
Example fix
// before: silent direct fallback on proxy failure
proxyOptions: { proxyUrl: "http://127.0.0.1:9999" }
// after: hard-fail when the proxy is required
proxyOptions: { proxyUrl: "http://127.0.0.1:9999", strictProxy: true } Defensive patterns
Strategy: try-catch
Validate before calling
const u = new URL(proxyUrl);
if (!/^https?:$/.test(u.protocol)) throw new Error('proxy must be http(s)');
await fetch('http://' + u.host + '/', { signal: AbortSignal.timeout(3000) }); // proxy reachable? Type guard
const isProxyFailure = (e) => e instanceof Error && /Proxy required but failed|proxy/i.test(e.message);
Try / catch
try {
return await proxyAwareFetch(url, { proxyOptions });
} catch (e) {
if (isProxyFailure(e)) {
// strictProxy threw — proxy is mandatory in this environment
console.error('proxy mandatory but down:', e.message);
}
throw e;
} Prevention
- Health-check the proxy at startup and periodically
- Include credentials in the proxy URL if the proxy requires auth (407)
- Match the proxy URL scheme to its actual type (http vs socks5)
- Set strictProxy=true in environments where direct egress is forbidden, so failures are loud
- Monitor this warning — frequent direct bypass may silently leak traffic past the proxy
When it happens
Trigger: The proxied fetch threw — proxy host unreachable/wrong port, proxy auth rejected (407), proxy timeout, TLS failure through the proxy, or getDispatcher failed to build an agent for the proxy URL.
Common situations: Proxy server down or the wrong address/port in proxy config; corporate proxy requires credentials not supplied; SOCKS vs HTTP proxy type mismatch; firewall blocks the proxy port; proxy certificate issues.
Related errors
- [ProxyFetch] Proxy failed, falling back to direct: ${proxyEr
- Failed to consume Codex reset credit: ${error.message}
- [ProxyFetch] Proxy required but failed (strictProxy=true): $
- [ProxyFetch] got-scraping unavailable, falling back to nativ
- [Codex Reset Credits] force refresh failed: ${retryError.mes
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/d9c184a78cfc98a6.
Report an issue: GitHub.