{"record":{"id":"63c313f2bb2ed481","repo":"abiosoft/colima","slug":"cannot-seek-to-start-of-file-w","errorCode":null,"errorMessage":"cannot seek to start of file: %w","messagePattern":"cannot seek to start of file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/downloader/http.go","lineNumber":163,"sourceCode":"\tif err != nil {\n\t\treturn nil, &NetworkError{Op: \"download\", URL: opts.URL, Err: err}\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\t// store final URL after redirects\n\tresult.FinalURL = resp.Request.URL.String()\n\tresult.ETag = resp.Header.Get(\"ETag\")\n\n\t// handle response status\n\tswitch resp.StatusCode {\n\tcase http.StatusOK: // 200 - Full content (resume not supported or If-Range failed)\n\t\tif existingSize > 0 {\n\t\t\t// server sent full content, need to truncate and start over\n\t\t\tif err := file.Truncate(0); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot truncate file for fresh download: %w\", err)\n\t\t\t}\n\t\t\tif _, err := file.Seek(0, 0); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot seek to start of file: %w\", err)\n\t\t\t}\n\t\t\texistingSize = 0\n\t\t}\n\t\tresult.TotalBytes = resp.ContentLength\n\n\tcase http.StatusPartialContent: // 206 - Resume successful\n\t\tresult.WasResumed = true\n\t\t// Content-Range: bytes 21010-47021/47022\n\t\tcontentRange := resp.Header.Get(\"Content-Range\")\n\t\tif totalSize := parseContentRangeTotal(contentRange); totalSize > 0 {\n\t\t\tresult.TotalBytes = totalSize\n\t\t} else {\n\t\t\tresult.TotalBytes = existingSize + resp.ContentLength\n\t\t}\n\n\tcase http.StatusRequestedRangeNotSatisfiable: // 416\n\t\t// file is likely complete or server doesn't support range\n\t\treturn nil, &HTTPStatusError{","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/abiosoft/colima/blob/c3a5f9184d83a197184f897a9f07eb3c01b3bc88/util/downloader/http.go#L145-L181","documentation":"Immediately after a successful truncate (case: 200 response with existing partial), file.Seek(0, 0) on the same descriptor failed. It is the same failure class as error 266 — the underlying file or storage went bad mid-operation; the fd was valid because truncate had just succeeded on it.","triggerScenarios":"Storage I/O error or external interference (unmounted volume, AV file-locking) on the .downloading file during the restart-from-zero after a 200 response.","commonSituations":"Failing or ejected disk holding the cache; aggressive antivirus scanning the cache dir.","solutions":["Remove the .downloading partial and .resume info and retry fresh","Check disk health (Disk Utility, smartctl) and remount the volume","Exclude the cache dir from real-time AV scanning"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := fileDownloader.Download(req, dest)\nif err != nil && strings.Contains(err.Error(), \"cannot seek to start of file\") {\n    base := strings.TrimSuffix(dest, \".downloading\")\n    _ = os.Remove(dest)\n    _ = os.Remove(base + \".resume\")\n    err = fileDownloader.Download(req, dest)\n}\nif err != nil {\n    return err\n}","preventionTips":["Treat seek/truncate failures on the same file as a storage health signal","Exclude the cache dir from antivirus real-time scanning on macOS"],"tags":["download","resume","filesystem","io"],"backgroundTag":null,"analyzedSha":"c3a5f9184d83a197184f897a9f07eb3c01b3bc88","analyzedAt":"2026-08-15T18:58:08.334Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}