henrygd/beszel · error
write tmp: %w
Error message
write tmp: %w
What it means
Thrown by downloadFile when io.Copy fails writing the response body into the temp file (via the optional MultiWriter that also feeds the hasher). It wraps either a disk write error or a network read error from the response body mid-transfer. The temp file is closed and removed on failure.
Source
Thrown at agent/tools/fetchsmartctl/main.go:97
case 40:
hasher = sha1.New()
case 64:
hasher = sha256.New()
default:
f.Close()
os.Remove(tmp)
return fmt.Errorf("unsupported hash length: %d (expected 40 for SHA1 or 64 for SHA256)", len(cleanSha))
}
}
var mw io.Writer = f
if hasher != nil {
mw = io.MultiWriter(f, hasher)
}
if _, err := io.Copy(mw, resp.Body); err != nil {
f.Close()
os.Remove(tmp)
return fmt.Errorf("write tmp: %w", err)
}
if err := f.Close(); err != nil {
os.Remove(tmp)
return fmt.Errorf("close tmp: %w", err)
}
if hasher != nil && shaHex != "" {
cleanSha := strings.ToLower(strings.ReplaceAll(strings.TrimSpace(shaHex), " ", ""))
got := strings.ToLower(hex.EncodeToString(hasher.Sum(nil)))
if got != cleanSha {
os.Remove(tmp)
return fmt.Errorf("hash mismatch: got %s want %s", got, cleanSha)
}
}
// Make executable and move into place
if err := os.Chmod(tmp, 0o755); err != nil {
os.Remove(tmp)View on GitHub (pinned to b38fb7dafa)
Solutions
- Inspect the wrapped %w error: 'no space left' → free disk space; 'connection reset/unexpected EOF' → network issue
- Retry the download — transient network drops are the most common cause
- Ensure destination volume has free space larger than the binary size
- Increase client timeout or add resume/retry logic for large files
Example fix
// before
if _, err := io.Copy(mw, resp.Body); err != nil {
f.Close()
os.Remove(tmp)
return fmt.Errorf("write tmp: %w", err)
}
// after
if _, err := io.Copy(mw, resp.Body); err != nil {
f.Close()
os.Remove(tmp)
return fmt.Errorf("write tmp (disk full or connection dropped?): %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
if free, err := diskFree(filepath.Dir(dest)); err == nil && free < minRequiredBytes {
return fmt.Errorf("only %d bytes free, need ~%d", free, minRequiredBytes)
} Try / catch
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
lastErr = downloadFile(url, dest, sha)
if lastErr == nil || !strings.HasPrefix(lastErr.Error(), "write tmp:") {
break
}
time.Sleep(time.Duration(1<<attempt) * time.Second)
}
if lastErr != nil {
return lastErr
} Prevention
- Ensure the destination volume has free space larger than the expected download
- Retry downloads once on transient network errors
- Avoid downloading over flaky links or unstable proxies
- Use wired/stable network or resumable HTTP (Range) for large files
When it happens
Trigger: Disk fills during the download (ENOSPC), the connection drops mid-body (unexpected EOF, connection reset), or the filesystem rejects the write partway.
Common situations: Flaky Wi-Fi/CI network interrupting large downloads; full disk or small tmpfs holding the destination; proxy killing long-lived connections; quota exceeded.
Related errors
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/66151f8698d17675.
Report an issue: GitHub.