MHSanaei/3x-ui · error
download panel updater: unexpected HTTP %d
Error message
download panel updater: unexpected HTTP %d
What it means
The updater script URL answered, but with a non-200 status — the download is refused at the HTTP layer. Typical codes: 404 (script moved / wrong release tag, e.g. a dev channel request against a tag that has no asset), 403 (rate-limited or blocked by the host/CDN), 5xx. The response body is discarded; only the code is reported.
Source
Thrown at internal/web/service/panel/panel.go:369
func releaseUpdateSlot() {
updateMu.Lock()
updateRunning = false
updateMu.Unlock()
}
func downloadPanelUpdater() (string, error) {
client := (&service.SettingService{}).NewProxiedHTTPClient(15 * time.Second)
req, reqErr := http.NewRequestWithContext(context.Background(), http.MethodGet, panelUpdaterURL, nil)
if reqErr != nil {
return "", fmt.Errorf("download panel updater: %w", reqErr)
}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("download panel updater: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("download panel updater: unexpected HTTP %d", resp.StatusCode)
}
file, err := os.CreateTemp("", "3x-ui-update-*.sh")
if err != nil {
return "", err
}
path := file.Name()
ok := false
defer func() {
_ = file.Close()
if !ok {
_ = os.Remove(path)
}
}()
n, err := io.Copy(file, io.LimitReader(resp.Body, maxPanelUpdaterBytes+1))
if err != nil {
return "", fmt.Errorf("write panel updater: %w", err)View on GitHub (pinned to ad32144c42)
Solutions
- Reproduce the exact code: curl -sI <updater-url> from the server
- 404 -> the URL/tag is stale; update the panel via the official install script or wait for an upstream fix
- 403/429 -> rate-limited; wait and retry, or route through the configured proxy
- 5xx -> upstream outage; retry later
Example fix
curl -sI https://raw.githubusercontent.com/MHSanaei/3x-ui/master/install.sh # HTTP 404 -> channel tag wrong; use the stable channel or update manually: # bash <(curl -fsSL https://raw.githubusercontent.com/MHSanaei/3x-ui/master/install.sh)
Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Head(panelUpdaterURL) // through same proxy
if err == nil && resp.StatusCode != http.StatusOK {
return fmt.Errorf("updater host returned %d; defer update", resp.StatusCode)
} Try / catch
_, err := panelService.StartUpdate(false)
if err != nil && strings.Contains(err.Error(), "unexpected HTTP") {
// 404 = stale asset, stop; 403/429/5xx = rate limit/outage, retry with backoff
} Prevention
- Avoid hammering update checks (rate limits on the script host)
- Fall back to the official manual install script when the hosted asset 404s
When it happens
Trigger: Panel update triggered when the upstream host returns 404/403/5xx for panelUpdaterURL — e.g. the script was relocated, the release asset is missing for the requested channel, or CDN rate limiting kicked in.
Common situations: GitHub rate limiting an automated/frequent update check; upstream repo reorganization that moved the script; requesting the dev channel before its release assets exist.
Related errors
- dev release commit is unknown
- a panel update is already in progress
- panel web update is supported only on Linux installations
- bash is required to run the panel updater: %w
- failed to start panel update job: %w: %s
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/1d04b4a98b09a8b1.
Report an issue: GitHub.