XTLS/Xray-core · error · errors.Error
unexpected status code:
Error message
unexpected status code:
What it means
Returned by downloadOne after a geodata HTTP response arrives with a status code outside 200-299. The body is drained/discarded and the numeric status is embedded in the message.
Source
Thrown at app/geodata/download.go:213
return err
}
utils.TryDefaultHeadersWith(req.Header, "nav")
var client *http.Client
if req.URL.Scheme == "https" {
client = d.httpsClient
} else {
client = d.httpClient
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
io.Copy(io.Discard, resp.Body)
return errors.New("unexpected status code: ", resp.StatusCode)
}
n, err := io.Copy(writer, resp.Body)
if err != nil {
return err
}
if n == 0 {
return errors.New("empty response body")
}
return nil
}
func clean(assets []stage) {
for _, asset := range assets {
if asset.temp != "" {
os.Remove(asset.temp)
}
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Open the exact asset URL in a browser/curl to confirm it returns 200
- For 403/429 rate limiting, switch mirrors or add delay between updates (widen the geodata cron)
- For 404, correct the asset path or use the default asset URLs
- Retry later for 5xx outages
Defensive patterns
Strategy: try-catch
Validate before calling
// Health-check the asset URL before the cron fires:
resp, err := http.Head(assetURL)
if err != nil || resp.StatusCode < 200 || resp.StatusCode >= 300 {
// mark mirror unhealthy, use fallback URL
} Try / catch
resp, err := client.Do(req)
if err == nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
switch resp.StatusCode {
case 403, 429:
time.Sleep(time.Minute) // rate limited: back off before retry
case 404:
return fmt.Errorf("asset missing at %s; fix URL", req.URL) // permanent
default:
// transient 5xx: retry later
}
} Prevention
- Use official, stable mirrors for geodata assets
- Space geodata updates via cron to avoid rate limits
- Verify asset URLs return 200 during config review
When it happens
Trigger: client.Do for a geodata asset returns e.g. 404 (file removed / wrong path), 403 (rate limited or blocked CDN), 5xx (mirror outage), or 301 leaking through when redirects were stopped.
Common situations: Wrong asset URL path after a repo reorganization; GitHub raw rate limiting; mirror temporarily down; asset name typo like 'geosites.dat' instead of 'geosite.dat'.
Related errors
- connection idle timeout
- cannot understand address
- cannot dial remote address
- cannot finish connection
- redirected to non-https URL:
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/5497f2281cc76f69.
Report an issue: GitHub.