Skip to content

Commit fc9c971

Browse files
fix(downloader): retry checksum mismatches
A remote can serve stale or corrupted bytes for one request. Mark the integrity failure as transient so the bounded download planner retries it. Assisted-by: Codex:gpt-5.6
1 parent 88edd7f commit fc9c971

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

pkg/downloader/retry_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,37 @@ var _ = Describe("DownloadFilesWithContext retries", func() {
179179
}
180180
})
181181

182+
It("retries a checksum mismatch", func() {
183+
wrongPayload := []byte("stale model bytes")
184+
requests := 0
185+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
186+
requests++
187+
body := payload
188+
if requests == 1 {
189+
body = wrongPayload
190+
}
191+
w.Header().Set("Content-Length", strconv.Itoa(len(body)))
192+
w.WriteHeader(http.StatusOK)
193+
_, _ = w.Write(body)
194+
}))
195+
DeferCleanup(server.Close)
196+
197+
err := downloader.DownloadFilesWithContext(context.Background(), []downloader.FileTask{{
198+
URI: downloader.URI(server.URL),
199+
Destination: destPath,
200+
SHA256: payloadSHA,
201+
FileIndex: 1,
202+
TotalFiles: 1,
203+
}}, nil)
204+
Expect(requests).To(Equal(2), "the checksum failure must trigger one retry")
205+
Expect(err).ToNot(HaveOccurred())
206+
207+
got, err := os.ReadFile(destPath)
208+
Expect(err).ToNot(HaveOccurred())
209+
Expect(got).To(Equal(payload))
210+
Expect(destPath + downloader.PartialFileSuffix).ToNot(BeAnExistingFile())
211+
})
212+
182213
It("does not retry a permanent failure", func() {
183214
attempts := 0
184215
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

pkg/downloader/uri.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ func (uri URI) DownloadFileWithContext(ctx context.Context, filePath, sha string
850850
if calculatedSHA != sha {
851851
xlog.Debug("SHA mismatch for file", "file", filePath, "calculated", calculatedSHA, "metadata", sha)
852852
_ = removePartialFile(tmpFilePath)
853-
return fmt.Errorf("SHA mismatch for file %q ( calculated: %s != metadata: %s )", filePath, calculatedSHA, sha)
853+
return asTransient(fmt.Errorf("SHA mismatch for file %q ( calculated: %s != metadata: %s )", filePath, calculatedSHA, sha))
854854
}
855855
} else {
856856
// Visible at the default log level so missing-digest configs are

0 commit comments

Comments
 (0)