{"record":{"id":"3a0699eb9c7bae9b","repo":"kopia/kopia","slug":"error-copying-blobs","errorCode":null,"errorMessage":"error copying blobs","messagePattern":"error copying blobs","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command_repository_sync.go","lineNumber":283,"sourceCode":"\t\t\t\t\t\tnumBlobs, units.BytesString(bytesCopied), speed, eta))\n\n\t\t\t\tprogressMutex.Unlock()\n\t\t\t}\n\n\t\t\tfor m := range deleteCh {\n\t\t\t\tlog(ctx).Debugf(\"[%v] Deleting %v (%v bytes)...\\n\", workerID, m.BlobID, m.Length)\n\n\t\t\t\tif err := syncDeleteBlob(ctx, m, dst); err != nil {\n\t\t\t\t\treturn errors.Wrapf(err, \"error deleting %v\", m.BlobID)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn nil\n\t\t})\n\t}\n\n\tif err := eg.Wait(); err != nil {\n\t\treturn errors.Wrap(err, \"error copying blobs\")\n\t}\n\n\treturn nil\n}\n\nfunc sliceToChannel(ctx context.Context, md []blob.Metadata) chan blob.Metadata {\n\tch := make(chan blob.Metadata)\n\n\tgo func() {\n\t\tdefer close(ch)\n\n\t\tfor _, it := range md {\n\t\t\tselect {\n\t\t\tcase ch <- it:\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/kopia/kopia/blob/82495e54b584c1ef6073c9e1be048f57f8aef078/cli/command_repository_sync.go#L265-L301","documentation":"This is the outer wrapper around errgroup.Wait() in runSyncBlobs for 'repository sync to'. It aggregates any error returned by the parallel copy/delete worker goroutines (which are already wrapped with 'error copying <id>' or 'error deleting <id>'), so the developer sees the sync's blob-transfer phase failed; the specific BLOB and root cause are in the wrapped chain.","triggerScenarios":"Any of the worker goroutines in runSyncBlobs returns an error: a syncCopyBlob failure on copyCh items or a syncDeleteBlob failure on deleteCh items; the first error cancels the errgroup context and stops the remaining workers.","commonSituations":"Mid-sync network outage to source or destination; destination storage throttling under parallelism; permission errors surfacing during copy or delete phases; Ctrl-C / context cancellation mid-run.","solutions":["Re-run the sync; it is idempotent and will resume with the BLOBs still missing at the destination","Look at the inner 'error copying <blobID>'/'error deleting <blobID>' and underlying cause for the actual fix","Reduce parallelism or check network stability if throttling/timeouts caused the failure","Fix destination permissions/quotas before retrying if the inner error indicates access or capacity issues"],"exampleFix":"// before: transient failure aborts run\nkopia repository sync to s3 --bucket=dest   // fails: error copying blobs -> error copying abc123\n// after: simply retry, sync resumes\nkopia repository sync to s3 --bucket=dest","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := kopiaSyncTo(ctx, opts); err != nil {\n    if strings.Contains(err.Error(), \"error copying blobs\") {\n        log.Printf(\"sync aborted mid-transfer: %v; retrying (idempotent)\", err)\n        return retryWithBackoff(ctx, kopiaSyncTo, opts)\n    }\n    return err\n}","preventionTips":["Treat sync as resumable — rerun after transient failures instead of manual repairs","Keep network connections stable; avoid suspending machines mid-sync","Reduce parallelism on throttled backends","Unwrap the inner 'error copying/deleting <blobID>' message to target root causes"],"tags":["storage","blob-copy","concurrency","errgroup"],"backgroundTag":"network-request-failed","analyzedSha":"82495e54b584c1ef6073c9e1be048f57f8aef078","analyzedAt":"2026-09-07T20:35:21.689Z","contentChangedAt":"2026-09-07T20:35:21.689Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}