abiosoft/colima · error
cannot truncate file for fresh download: %w
Error message
cannot truncate file for fresh download: %w
What it means
The server answered 200 (full body) while a partial file existed for resume (If-Range/ETag path failed or Range unsupported), so the code must restart from byte 0 and calls file.Truncate(0) on the .downloading partial — and the truncate failed. Reached only when existingSize > 0; the wrapped error is a filesystem failure on the partial (I/O error, storage dropped, file replaced concurrently).
Source
Thrown at util/downloader/http.go:160
// execute request
resp, err := h.client.Do(req)
if err != nil {
return nil, &NetworkError{Op: "download", URL: opts.URL, Err: err}
}
defer func() { _ = resp.Body.Close() }()
// store final URL after redirects
result.FinalURL = resp.Request.URL.String()
result.ETag = resp.Header.Get("ETag")
// handle response status
switch resp.StatusCode {
case http.StatusOK: // 200 - Full content (resume not supported or If-Range failed)
if existingSize > 0 {
// server sent full content, need to truncate and start over
if err := file.Truncate(0); err != nil {
return nil, fmt.Errorf("cannot truncate file for fresh download: %w", err)
}
if _, err := file.Seek(0, 0); err != nil {
return nil, fmt.Errorf("cannot seek to start of file: %w", err)
}
existingSize = 0
}
result.TotalBytes = resp.ContentLength
case http.StatusPartialContent: // 206 - Resume successful
result.WasResumed = true
// Content-Range: bytes 21010-47021/47022
contentRange := resp.Header.Get("Content-Range")
if totalSize := parseContentRangeTotal(contentRange); totalSize > 0 {
result.TotalBytes = totalSize
} else {
result.TotalBytes = existingSize + resp.ContentLength
}
View on GitHub (pinned to c3a5f9184d)
Solutions
- Delete the .downloading partial and the .resume info, then retry for a clean fresh download
- Move the cache dir onto reliable local storage
- Avoid concurrent downloads sharing the same cache dir
Example fix
# before: resume hits a 200, truncate fails on the poisoned partial
# after: force a fresh download
cache=$(limactl ... ) # sha256-named entry under <cachedir>/caches
rm -f "${cache}.downloading" "${cache}.resume" Defensive patterns
Strategy: retry
Try / catch
err := fileDownloader.Download(req, dest)
if err != nil && strings.Contains(err.Error(), "cannot truncate file for fresh download") {
base := strings.TrimSuffix(dest, ".downloading")
_ = os.Remove(dest) // poisoned partial
_ = os.Remove(base + ".resume") // stale resume info
err = fileDownloader.Download(req, dest)
}
if err != nil {
return err
} Prevention
- Keep the cache dir on reliable local storage, not network volumes
- Do not run two resumable downloads against the same partial file
- On unexplained truncate failures, suspect disk health before retrying endlessly
When it happens
Trigger: Resume attempt against a server that ignores Range headers; the partial file sits on a network/external volume that errors on truncate; another process deleted/replaced the partial between open and truncate.
Common situations: Cache stored on flaky external storage; two colima processes resuming the same URL; disk faults.
Related errors
- cannot seek to start of file: %w
- error preparing cache dir: %w
- cannot create file '%s': %w
- error downloading '%s': %w
- error persisting runtime settings: %w
AI-assisted analysis of abiosoft/colima@c3a5f9184d (2026-08-15).
Data as JSON: /api/errors/051392ec22b0342d.
Report an issue: GitHub.