koala73/worldmonitor · error · RssProxyPolicyError
Too many redirects
Error message
Too many redirects
What it means
Thrown by the direct-fetch redirect loop in the RSS proxy when the redirect chain exceeds MAX_DIRECT_REDIRECTS (3). The proxy manually follows redirects (to apply protocol and domain checks on each hop) and after 3 redirects it stops and throws RssProxyPolicyError with HTTP status 502. This prevents infinite redirect loops and bounds latency.
Source
Thrown at api/rss-proxy.js:169
let currentUrl = parsedUrl;
for (let redirectCount = 0; redirectCount <= MAX_DIRECT_REDIRECTS; redirectCount += 1) {
const response = await fetchWithTimeout(currentUrl.href, {
headers: DIRECT_FETCH_HEADERS,
redirect: 'manual',
}, timeout);
if (!DIRECT_REDIRECT_STATUSES.has(response.status)) {
return response;
}
const location = response.headers.get('location');
if (!location) {
return response;
}
if (redirectCount === MAX_DIRECT_REDIRECTS) {
throw new RssProxyPolicyError('Too many redirects', 502);
}
const redirectUrl = new URL(location, currentUrl.href);
assertAllowedRedirect(redirectUrl);
currentUrl = redirectUrl;
}
};
let response;
let usedRelay = false;
if (isRelayOnly) {
// Skip direct fetch entirely — these domains block Vercel IPs
response = await fetchViaRailway(feedUrl, timeout);
usedRelay = !!response;
if (!response) throw new Error(`Railway relay unavailable for relay-only domain: ${hostname}`);
} else {
try {View on GitHub (pinned to ffec79ac33)
Solutions
- Find the final canonical feed URL (follow the redirects manually in a browser or with curl -L) and use that URL directly to avoid the chain.
- If the domain consistently requires many redirects, add it to RELAY_ONLY_DOMAINS so the proxy uses the Railway relay (which handles redirects differently) instead of the bounded direct path.
- If the feed has a redirect loop (same URLs cycling), report it to the feed provider — this is a server misconfiguration.
- Increase MAX_DIRECT_REDIRECTS only if you understand the latency and loop-risk tradeoffs (not recommended for an edge function).
Example fix
// before — long redirect chain triggers the limit GET /api/rss-proxy?url=http://old.feeds.example.com/news.xml // after — use the final canonical URL directly GET /api/rss-proxy?url=https://cdn.feeds.example.com/news.xml
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-resolve the feed URL to find its final canonical form
async function resolveCanonicalFeedUrl(feedUrl) {
let url = feedUrl;
for (let i = 0; i < 5; i++) { // one more than MAX_DIRECT_REDIRECTS to detect the issue
const res = await fetch(url, { method: 'HEAD', redirect: 'manual' });
const location = res.headers.get('location');
if (!location || ![301,302,303,307,308].includes(res.status)) return url;
url = new URL(location, url).href;
}
throw new Error(`Feed URL exceeds redirect limit; canonical URL: ${url}`);
} Type guard
function isTooManyRedirectsError(e: unknown): e is { status: number } & Error {
return e instanceof Error && (e as any).name === 'RssProxyPolicyError' && e.message === 'Too many redirects';
} Try / catch
try {
const feed = await fetch('/api/rss-proxy?url=' + encodeURIComponent(feedUrl));
} catch (e) {
if (isTooManyRedirectsError(e)) {
// Resolve the canonical URL and use it directly
const canonical = await resolveCanonicalFeedUrl(feedUrl);
const feed = await fetch('/api/rss-proxy?url=' + encodeURIComponent(canonical));
} else throw e;
} Prevention
- Find and store the final canonical feed URL instead of relying on the proxy to follow long chains.
- Add feeds with persistent redirect issues to RELAY_ONLY_DOMAINS to use the Railway relay path.
- Monitor for redirect loops — they indicate server misconfiguration on the feed origin.
When it happens
Trigger: An RSS feed URL that redirects more than 3 times before reaching a non-redirect (200/4xx/5xx) response — e.g. a feed that bounces between http and https, between apex and www, through a CDN chain, or a misconfigured redirect loop (A->B->A). Only 301/302/303/307/308 statuses count as redirects (DIRECT_REDIRECT_STATUSES).
Common situations: A feed behind multiple CDN layers (origin -> CDN -> www); a feed with an http-to-https redirect combined with an apex-to-www redirect (2 hops) plus one more; a genuine redirect loop from a misconfigured server; a feed that moved and chains through several old URLs.
Related errors
- Redirect to disallowed domain
- URL protocol not allowed
- Railway relay unavailable for relay-only domain: ${hostname}
- Redis not configured
- payload_too_large
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/dcc91d8c0cf296a7.
Report an issue: GitHub.