XTLS/Xray-core · error

unexpected HTTP status code: %d

Error message

unexpected HTTP status code: %d

What it means

After a successful fetch, fetchHTTPContent requires exactly HTTP 200; any other status — including other 2xx codes like 204, and all redirects that aren't auto-followed for hand-built requests — is rejected with the numeric code.

Source

Thrown at main/commands/all/api/shared.go:100

	if s := strings.ToLower(parsedTarget.Scheme); s != "http" && s != "https" {
		return nil, fmt.Errorf("invalid scheme: %s", parsedTarget.Scheme)
	}

	client := &http.Client{
		Timeout: 30 * time.Second,
	}
	resp, err := client.Do(&http.Request{
		Method: "GET",
		URL:    parsedTarget,
		Close:  true,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to dial to %s", target)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("unexpected HTTP status code: %d", resp.StatusCode)
	}

	content, err := buf.ReadAllToBytes(resp.Body)
	if err != nil {
		return nil, errors.New("failed to read HTTP response")
	}

	return content, nil
}

func showJSONResponse(m proto.Message) {
	if isNil(m) {
		return
	}
	if j, ok := creflect.MarshalToJson(m, true); ok {
		fmt.Println(j)
	} else {
		fmt.Fprintf(os.Stdout, "%v\n", m)

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. curl -I the URL to see the actual status and Location header
  2. Update the URL to a current, direct (non-redirecting) source
  3. For 403: add a User-Agent or use a different mirror if the server filters clients
  4. Host the file locally to remove the dependency

Example fix

# before: 404
"downloadUrl": "https://old-mirror/geoip.dat"
# after (verified with curl -I → 200)
"downloadUrl": "https://new-mirror/geoip.dat"
Defensive patterns

Strategy: fallback

Validate before calling

// pre-flight: expect exactly 200
resp, err := http.Head(url)
if err == nil && resp.StatusCode != 200 {
    return fmt.Errorf("source returned %d — pick another mirror", resp.StatusCode)
}

Try / catch

body, err := fetchHTTPContent(target)
if err != nil && strings.Contains(err.Error(), "unexpected HTTP status code") {
    for _, mirror := range mirrors { // fallback list
        if body, err = fetchHTTPContent(mirror); err == nil { break }
    }
}

Prevention

When it happens

Trigger: Server returns 403/404/5xx for the resource URL; a 204 or 206 response; a redirect (301/302) that the constructed http.Request did not follow because the URL host/path changed or the client's redirect policy was hit.

Common situations: Geo resource moved or removed upstream (404); CDN rate-limiting or geo-blocking (403); authenticated endpoints returning 401; mirrors returning redirects to signed URLs.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/067c5799a24ae42b. Report an issue: GitHub.