henrygd/beszel · error

unexpected HTTP status: %s

Error message

unexpected HTTP status: %s

What it means

Thrown by downloadFile when the server responds with a non-2xx status code (e.g. 404 Not Found, 403 Forbidden, 503). The message includes the full status string so you can see exactly what the remote returned. The download is aborted before writing any bytes.

Source

Thrown at agent/tools/fetchsmartctl/main.go:65

		return fmt.Errorf("create dir: %w", err)
	}

	// HTTP client
	client := &http.Client{Timeout: 60 * time.Second}
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return fmt.Errorf("new request: %w", err)
	}
	req.Header.Set("User-Agent", "beszel-fetchsmartctl/1.0")

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("http get: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		return fmt.Errorf("unexpected HTTP status: %s", resp.Status)
	}

	tmp := dest + ".tmp"
	f, err := os.OpenFile(tmp, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
	if err != nil {
		return fmt.Errorf("open tmp: %w", err)
	}

	// Determine hash algorithm based on length (SHA1=40, SHA256=64)
	var hasher hash.Hash
	if shaHex := strings.TrimSpace(shaHex); shaHex != "" {
		cleanSha := strings.ToLower(strings.ReplaceAll(shaHex, " ", ""))
		switch len(cleanSha) {
		case 40:
			hasher = sha1.New()
		case 64:
			hasher = sha256.New()
		default:

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Read the status in the message: 404 means the URL/version is wrong — update to the current release URL
  2. 403 often means rate limiting or proxy auth — check proxy settings or retry later
  3. 5xx means server-side trouble — retry with backoff
  4. Verify the URL manually with curl -I

Example fix

// before
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
	return fmt.Errorf("unexpected HTTP status: %s", resp.Status)
}
// after
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
	return fmt.Errorf("unexpected HTTP status %s for %s", resp.Status, url)
}
Defensive patterns

Strategy: retry

Validate before calling

resp, err := http.Head(url)
if err == nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
	return fmt.Errorf("URL %s returns %s before download", url, resp.Status)
}

Try / catch

if err := downloadFile(url, dest, sha); err != nil {
	if strings.Contains(err.Error(), "unexpected HTTP status") {
		fmt.Printf("server said: %s — check the release URL/version\n", err)
		os.Exit(3)
	}
	return err
}

Prevention

When it happens

Trigger: The smartmontools release URL is wrong, the version/tag no longer exists, the CDN returns 403/404, or a proxy intercepts with an error page.

Common situations: Upstream release replaced/moved (version bump in the tool's URL list); rate limiting from GitHub; typo'd version in build config; corporate proxy blocking the domain.

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/907688c1d6e01536. Report an issue: GitHub.