decolua/9router · warning
[ProxyFetch] Proxy failed, falling back to direct: ${proxyEr
Error message
[ProxyFetch] Proxy failed, falling back to direct: ${proxyError.message} What it means
In the got-scraping code path, the proxied fetch is attempted first; on failure (and when strictProxy is not true) it logs this warning and re-issues the request with plain native fetch without the dispatcher, i.e. direct connection. Like the dispatcher path, strictProxy=true turns the proxy failure into a thrown error instead.
Source
Thrown at open-sse/utils/proxyFetch.js:346
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 direct
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: ${proxyError.message}`);
return originalFetch(url, options);
}
}
// got-scraping disabled — use native fetch directly
// (Re-enable per-host by wrapping with tryGotScrapingFetch when needed)
return originalFetch(url, options);
}
/**
* Patched global fetch with env-proxy support and MITM DNS bypass
*/
async function patchedFetch(url, options = {}) {
return proxyAwareFetch(url, options, null);
}
// Idempotency guard — only patch once to avoid wrapping multiple times
if (globalThis.fetch !== patchedFetch) {View on GitHub (pinned to 90b52e06ff)
Solutions
- Verify proxy health and credentials; retry the request once the proxy is reachable
- Set strictProxy=true if direct egress is not allowed in your environment (forces a visible error instead of silent bypass)
- Check whether the specific upstream blocks the proxy's egress IP and add a different proxy
- Ensure the proxy URL scheme matches its type (http:// vs socks5://)
- Accept the fallback if direct access is fine — this warning is non-fatal
Example fix
// before proxyUrl: "http://user:oldpass@proxy:8080" // after: corrected credentials proxyUrl: "http://user:newpass@proxy:8080"
Defensive patterns
Strategy: try-catch
Validate before calling
const u = new URL(proxyUrl);
const probe = await fetch('http://' + u.host + '/', { signal: AbortSignal.timeout(3000) }).catch(() => null);
if (!probe) throw new Error(`proxy ${u.host} unreachable`); Type guard
const isProxyDown = (e) => e instanceof Error && /Proxy required but failed|fetch failed|ECONNREFUSED|407/i.test(e.message);
Try / catch
try {
return await proxyAwareFetch(url, { proxyOptions, strictProxy: true });
} catch (e) {
if (isProxyDown(e)) return directFetchWithRetry(url); // explicit, logged direct fallback
throw e;
} Prevention
- Test got-scraping + proxy path once at boot; alert if the probe fails
- Rotate proxy credentials before expiry to avoid 407s
- Use a proxy that permits got-scraping's TLS impersonation
- Set strictProxy=true to convert silent bypass into actionable errors
When it happens
Trigger: The browser-fingerprint (got-scraping) proxied request threw — proxy unreachable, 407 auth failure, upstream TLS handshake failure through the proxy, or connection timeout via the proxy dispatcher.
Common situations: Proxy credentials rotated; proxy allows only certain egress hosts; got-scraping's TLS impersonation rejected by the proxy; proxy connection pool exhausted; transient proxy outage during a burst of requests.
Related errors
- [ProxyFetch] got-scraping unavailable, falling back to nativ
- [ProxyFetch] Proxy failed, falling back to direct bypass: ${
- Failed to consume Codex reset credit: ${error.message}
- [ProxyFetch] Proxy required but failed (strictProxy=true): $
- [Codex Reset Credits] force refresh failed: ${retryError.mes
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/d9502f1d78152446.
Report an issue: GitHub.