glanceapp/glance · error
unexpected status code %d from %s
Error message
unexpected status code %d from %s
What it means
Returned by rssWidget.fetchItemsFromFeedTask (internal/glance/widget-rss.go:227) when a feed URL responds with a status other than 200 (or 304 when a cached copy exists). The request already carries a Glance user-agent; non-200 means the server refused or failed the fetch: 403 anti-bot, 404 moved feed, 410 gone, 429 rate-limited, or 5xx outage.
Source
Thrown at internal/glance/widget-rss.go:227
}
widget.cachedFeedsMutex.Unlock()
for key, value := range request.Headers {
req.Header.Set(key, value)
}
resp, err := defaultHTTPClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotModified && isCached {
return cache.items, nil
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code %d from %s", resp.StatusCode, request.URL)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
feed, err := feedParser.ParseString(string(body))
if err != nil {
return nil, err
}
if request.Limit > 0 && len(feed.Items) > request.Limit {
feed.Items = feed.Items[:request.Limit]
}
items := make(rssFeedItemList, 0, len(feed.Items))
View on GitHub (pinned to 91324e8de7)
Solutions
- Confirm the URL with curl -A 'Glance' and follow redirects to find the current feed address
- If the site blocks bots, use its RSS-specific domain or a feed proxy/burner URL that permits fetchers
- Increase the page cache-time so the feed is fetched less often (fixes 429)
- Remove feeds that are permanently gone (410)
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check a feed URL's health before adding it to the widget
resp, err := http.Get(feedURL)
if err != nil || (resp.StatusCode != 200 && resp.StatusCode != 304) {
// do not add / fix the URL
} Try / catch
if err != nil && strings.Contains(err.Error(), "unexpected status code") {
// 403 => bot blocking; 404/410 => moved/gone; 429 => back off; 5xx => retry later
} Prevention
- curl feeds with the Glance user-agent before adding them
- Prefer feed endpoints that permit fetchers
- Keep refresh intervals moderate to avoid 429s
When it happens
Trigger: GET {feed-url} returns 403 (Cloudflare/WAF blocking the Glance UA), 404/410 (feed path moved), 429 (refreshing too often), 301→non-200 chain where the redirect target errors, or 5xx from the origin. 304 is tolerated only when isCached is true; a 304 without cache still errors.
Common situations: Popular blogs behind Cloudflare blocking non-browser agents; feeds moved to /rss or /feed without redirect; widget refresh interval set aggressively low triggering 429s; origin outages.
Related errors
- unexpected status code %d when submitting challenge solution
- %w: missing %d RSS feeds
- session ID check request returned status %s
- non-200 response status: %s
- unexpected status code %d when requesting challenge page
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/9529468de01c19d5.
Report an issue: GitHub.