henrygd/beszel · error
%s returned status %d
Error message
%s returned status %d
What it means
checkHealth polls the hub's health endpoint and treats the service as healthy only when the HTTP status is exactly 200. Any other status (404, 403, 500, 502, 503) is reported with this error including the URL and received status, so callers can fail startup or keep wait-looping.
Source
Thrown at internal/cmd/hub/hub.go:99
healthCmd.Flags().StringVar(&baseURL, "url", "", "base URL")
healthCmd.MarkFlagRequired("url")
return healthCmd
}
// checkHealth checks the health of the hub.
func checkHealth(baseURL string) error {
client := &http.Client{
Timeout: time.Second * 3,
}
healthURL := baseURL + "/api/health"
resp, err := client.Get(healthURL)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("%s returned status %d", healthURL, resp.StatusCode)
}
return nil
}
View on GitHub (pinned to b38fb7dafa)
Solutions
- Check hub logs for startup errors; if still booting, retry — transient during rollout.
- Verify healthURL scheme/host/port/path matches the hub's actual health route; curl it from inside the network to compare.
- If a proxy returns 404, exempt the health endpoint from auth/routing rewrites.
- Confirm the port mapping points at the hub process; fix compose/port config and restart.
Example fix
// before
if resp.StatusCode != 200 {
return fmt.Errorf("%s returned status %d", healthURL, resp.StatusCode)
}
// after
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("%s returned status %d (hub may still be starting; check hub logs)", healthURL, resp.StatusCode)
} // pair with a retry/backoff loop in the caller Defensive patterns
Strategy: retry
Validate before calling
// probe the endpoint yourself before declaring failure
resp, err := http.Get(healthURL)
if err != nil || resp.StatusCode != http.StatusOK {
log.Printf("hub not ready yet (%v)", err)
} Try / catch
var err error
for i := 0; i < 30; i++ {
if err = checkHealth(healthURL); err == nil {
break
}
time.Sleep(2 * time.Second) // hub may still be starting
}
if err != nil {
log.Fatalf("health check failed: %v", err)
} Prevention
- Configure healthchecks with start_period/retries to tolerate boot time.
- Verify health URL path and port, especially behind reverse proxies.
- Exempt the health endpoint from auth middleware.
- Curl the endpoint from inside the network when debugging.
When it happens
Trigger: GET healthURL returns a non-200 response: the hub is still starting, the URL/port points at the wrong service, a reverse proxy intercepts the path (404/502), or auth middleware blocks the health route.
Common situations: Docker healthcheck racing container startup (503 during boot); health path misconfigured behind nginx/Traefik; port mapped to another container; hub crashed and the platform returns 502/503.
Related errors
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/0ce634417f66249d.
Report an issue: GitHub.