kopia/kopia · error
error writing pack
Error message
error writing pack
What it means
Returned by processWritePackResultLocked when an asynchronously written pack fails. The pending pack is moved back to failedPacks so a later Flush retries it; this error reports the writeErr from the background pack writer to the caller of writePackAndAddToIndexUnlocked/Locked.
Solutions
- Read writeErr in the chain — it is the original storage/preparation error.
- Call Flush() again; the pack was re-queued in failedPacks and will be retried.
- Check network stability and storage provider throttling (S3 503 SlowDown, etc.); consider retry-able blob storage options.
- If persistent, verify the storage backend is writable and not read-only (e.g. wrong bucket permissions, repository opened read-only by mistake).
Example fix
// before: assuming a failed pack write is fatal
if err := bm.writePackAndAddToIndexUnlocked(ctx, pp); err != nil {
return err
}
// after: failed packs are retried by Flush; surface but allow recovery
if err := bm.writePackAndAddToIndexUnlocked(ctx, pp); err != nil {
logger.Warnf("pack write failed (will retry on Flush): %v", err)
if retryErr := bm.Flush(ctx); retryErr != nil {
return retryErr
}
} Defensive patterns
Strategy: retry
Try / catch
// Go: failed packs are auto-requeued; retry via Flush
if err := bm.Flush(ctx); err != nil {
return errors.Wrap(err, "pack write failed; failed packs will be retried")
} Prevention
- Configure blob storage retry/timeout options for flaky networks
- Handle provider throttling (S3 SlowDown) with backoff at the storage layer
- Don't cancel the context while async pack writes are in flight
- Call Flush before Close so failed packs get a retry
When it happens
Trigger: writePackAndAddToIndexUnlocked detects pp.err set by the async writePackAndAddToIndexUnlocked goroutine (or the synchronous path fails); any error preparing or uploading the pack data blob surfaces here wrapped as 'error writing pack'.
Common situations: Background pack writer hit a transient storage failure (connection reset, throttling by S3); the context was canceled while the pack write was in flight; the pack blob failed integrity checks after upload.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- error writing previously failed pack
- can't save pack data blob
- error writing pack content
- error writing pending content
- unable to create pack
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/41b5a4f742737410.
Report an issue: GitHub.
Appendix: source
Thrown at repo/content/content_manager.go:562
// after finishing writing, remove from both writingPacks and failedPacks
bm.writingPacks = removePendingPack(bm.writingPacks, pp)
bm.failedPacks = removePendingPack(bm.failedPacks, pp)
if writeErr == nil {
// success, add pack index builder entries to index.
for _, info := range packFileIndex {
bm.packIndexBuilder.Add(info)
}
pp.currentPackData.Close()
return nil
}
// failure - add to failedPacks slice again
bm.failedPacks = append(bm.failedPacks, pp)
return errors.Wrap(writeErr, "error writing pack")
}
func (sm *SharedManager) prepareAndWritePackInternal(ctx context.Context, pp *pendingPackInfo, onUpload func(int64)) (index.Builder, error) {
ctx = contentlog.WithParams(ctx,
logparam.String("span:writePack", string(pp.packBlobID)))
mp, mperr := sm.format.GetMutableParameters(ctx)
if mperr != nil {
return nil, errors.Wrap(mperr, "mutable parameters")
}
packFileIndex, err := sm.preparePackDataContent(ctx, mp, pp)
if err != nil {
return nil, errors.Wrap(err, "error preparing data content")
}
if pp.currentPackData.Length() > 0 {
if err := sm.writePackFileNotLocked(ctx, pp.packBlobID, pp.currentPackData.Bytes(), onUpload); err != nil {View on GitHub (pinned to 82495e54b5)