MHSanaei/3x-ui · error
panel updater exceeds %d bytes
Error message
panel updater exceeds %d bytes
What it means
Returned when the panel updater body streams more than maxPanelUpdaterBytes (2 MiB, io.LimitReader caps at +1 byte so an over-limit download is detected, not just truncated). Because the updater script is small, an oversized body almost always means the URL returned something other than the updater — typically an HTML error page or login page from a proxy. Prevents writing and executing an arbitrary oversized payload.
Source
Thrown at internal/web/service/panel/panel.go:393
}
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)
}
if n == 0 {
return "", fmt.Errorf("panel updater download is empty")
}
if n > maxPanelUpdaterBytes {
return "", fmt.Errorf("panel updater exceeds %d bytes", maxPanelUpdaterBytes)
}
if err := file.Chmod(0o700); err != nil {
return "", err
}
ok = true
return path, nil
}
func fetchLatestPanelVersion() (string, error) {
release, err := fetchPanelRelease("")
if err != nil {
return "", err
}
if release.TagName == "" {
return "", fmt.Errorf("latest panel release tag is empty")
}
return release.TagName, nil
}View on GitHub (pinned to ad32144c42)
Solutions
- curl -sL the same URL and inspect Content-Type/size — HTML instead of the binary means proxy/captive-portal interception
- Fix or bypass the outbound proxy so the real asset is fetched
- If the genuine updater has grown past 2 MiB, bump maxPanelUpdaterBytes in internal/web/service/panel/panel.go and rebuild
Example fix
// before (panel.go:44) maxPanelUpdaterBytes = 2 << 20 // after — only if the real asset outgrew the cap maxPanelUpdaterBytes = 8 << 20
Defensive patterns
Strategy: validation
Validate before calling
resp, err := client.Head(assetURL)
if err == nil && resp.ContentLength > maxPanelUpdaterBytes {
return fmt.Errorf("asset of %d bytes exceeds updater cap; check proxy interception", resp.ContentLength)
}
Prevention
- Size-limit downloads with LimitReader(n+1) so over-cap is detected rather than truncated
- Log Content-Type on failed updater downloads — HTML means a proxy, not GitHub
- Review the cap constant whenever the upstream updater artifact changes shape
When it happens
Trigger: The updater URL is intercepted by a captive portal / proxy auth page (HTML, hundreds of KB to MBs); the release asset was replaced by a large artifact; a redirect page served inline instead of followed.
Common situations: Egress through an authenticating HTTP proxy; CDN edge serving a big block page; pointing the updater at a wrong tag whose asset is a full binary, not the small updater script.
Related errors
- write panel updater: %w
- panel updater download is empty
- download xray: archive exceeds %d bytes
- xray binary exceeds %d bytes
- remote response exceeds size limit
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/019c69365690c54a.
Report an issue: GitHub.