From a06df7a2de46ee15932a0fbfa27bc4bb0045acf8 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 3 Aug 2026 21:40:28 +0100 Subject: [PATCH] protondrive: fix corrupted uploads after a retried upload error - fixes #9722 When an upload failed part way through with a retryable error (eg a 502 from the block storage servers) the pacer retried the whole upload call with the same input stream. The stream had already been partially consumed, so the retry re-created the upload draft and committed just the remainder of the stream as a complete file, silently truncating it. With restic over serve restic this corrupted the repository as the truncated pack was reported as successfully uploaded. This fixes it by using CallNoRetry for the upload, as the other backends do, so retryable errors are returned wrapped in a RetryError for the caller to retry the upload with a fresh stream. --- backend/protondrive/protondrive.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/protondrive/protondrive.go b/backend/protondrive/protondrive.go index 2cd6b1f42..4e3e5933a 100644 --- a/backend/protondrive/protondrive.go +++ b/backend/protondrive/protondrive.go @@ -1114,7 +1114,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op modTime := src.ModTime(ctx) var linkID string var fileSystemAttrs *proton.RevisionXAttrCommon - if err = o.fs.pacer.Call(func() (bool, error) { + if err = o.fs.pacer.CallNoRetry(func() (bool, error) { linkID, fileSystemAttrs, err = o.fs.protonDrive.UploadFileByReader(ctx, folderLinkID, leaf, modTime, in, 0) return shouldRetry(ctx, err) }); err != nil {