MHSanaei/3x-ui · warning
http %d
Error message
http %d
What it means
After fetching the subscription, any status other than HTTP 200 is collapsed into 'http %d', recorded against the subscription via recordError (visible in the panel's last-error field), and returned. Common codes: 401/403 (bad token), 404 (wrong URL), 429 (rate limit), 5xx (provider down). The body is not read for a hint — the numeric code is the whole diagnostic.
Source
Thrown at internal/web/service/outbound_subscription.go:376
}
reqCtx := netsafe.ContextWithAllowPrivate(context.Background(), sub.AllowPrivate)
req, err := http.NewRequestWithContext(reqCtx, http.MethodGet, sub.Url, nil)
if err != nil {
s.recordError(sub, err)
return nil, err
}
req.Header.Set("User-Agent", "3x-ui-outbound-sub/1.0")
resp, err := client.Do(req)
if err != nil {
s.recordError(sub, err)
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err := fmt.Errorf("http %d", resp.StatusCode)
s.recordError(sub, err)
return nil, err
}
body, err := readBoundedOutboundSubscriptionBody(resp.Body)
if err != nil {
s.recordError(sub, err)
return nil, err
}
parsed, identities, err := link.ParseSubscriptionBody(body)
if err != nil {
s.recordError(sub, err)
return nil, err
}
// Load previous identities -> tags for stability
prev := map[string]string{}
if strings.TrimSpace(sub.LinkIdentities) != "" {View on GitHub (pinned to ad32144c42)
Solutions
- Reproduce with the same User-Agent to see the code: curl -sI -A '3x-ui-outbound-sub/1.0' <url>
- 401/403 -> get a fresh subscription URL/token from the provider
- 429 -> slow down the refresh schedule (subscription auto-update interval)
- 5xx -> provider-side outage; retry later
Example fix
curl -sI -A '3x-ui-outbound-sub/1.0' 'https://provider.example/sub?key=OLD' # HTTP/2 401 -> regenerate the link in the provider dashboard, paste the new URL into the outbound subscription
Defensive patterns
Strategy: retry
Validate before calling
resp, err := client.Get(sub.Url)
if err == nil {
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
// only now hand to the service
}
} Try / catch
_, err := client.Do(req)
if err != nil {
var httpErr error
if strings.HasPrefix(err.Error(), "http ") { /* actually returned by service, not transport */ }
// 429/5xx: retry with backoff; 401/403/404: surface 'subscription URL invalid'
} Prevention
- Set a sane auto-refresh interval to avoid 429s
- Rotate subscription tokens promptly when providers expire them
When it happens
Trigger: Refresh/update of an outbound subscription where the server answers 401, 403, 404, 429, 5xx, etc.
Common situations: Expired or rotated subscription token; URL typo; provider rate-limiting automated fetches; Cloudflare challenge page returning 403.
Related errors
- outbound subscription response body exceeds size limit (limi
- stopped after 10 redirects
- The current username or password is invalid
- The new username and password are empty
- node port must be 1-65535
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/46421e6ceef66885.
Report an issue: GitHub.