kopia/kopia · error
error writing index blob
Error message
error writing index blob
What it means
After index shards are built, flushPackIndexesLocked uploads them to storage via writeIndexBlobs, associating them with the current session ID. This error wraps a failure of that upload — the index blob(s) could not be written to the underlying blob storage. The session is not committed, so the new index entries are not yet visible to other clients, and Flush() fails.
Solutions
- Check the wrapped cause for the underlying provider error and HTTP status
- Verify and refresh storage credentials; confirm the bucket still allows writes
- Retry Flush after connectivity is restored — index writes are idempotent per session
- Test storage with a direct upload (e.g. aws s3 cp) to isolate the backend
- Check rate-limit responses and add backoff/retry configuration to the storage provider
Example fix
// before
repo.Flush(ctx) // fails silently into generic handler
// after
err := repo.Flush(ctx)
if err != nil && strings.Contains(err.Error(), "error writing index blob") {
refreshStorageCredentials()
time.Sleep(5 * time.Second)
err = repo.Flush(ctx)
} Defensive patterns
Strategy: retry
Validate before calling
// Go: confirm bucket is writable before flushing index blobs
if err := probeBlobWrite(ctx, storage); err != nil {
return fmt.Errorf("cannot write index blob: storage not writable: %w", err)
} Try / catch
err := repo.Flush(ctx)
if err != nil && strings.Contains(err.Error(), "error writing index blob") {
time.Sleep(retryDelay) // transient storage error
err = repo.Flush(ctx)
} Prevention
- Ensure credentials include write permissions for the entire session
- Check bucket policy/IAM changes before long runs
- Add exponential backoff at the storage provider layer
- Alert on storage 5xx and throttling during backups
When it happens
Trigger: Calling Flush (explicitly or via auto-flush/Close) while writeIndexBlobs fails — blob-storage upload errors such as network outage, expired cloud credentials, bucket permissions changed to read-only, or provider 5xx/throttling errors.
Common situations: Cloud storage credential expiry during long backup sessions; loss of connectivity to S3/GCS/Azure/BLOB endpoints; storage quota exceeded; accidental bucket policy change revoking write access mid-run.
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
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/e886c8a871dc90fd.
Report an issue: GitHub.
Appendix: source
Thrown at repo/content/content_manager.go:483
dataShards, closeShards, err := bm.packIndexBuilder.BuildShards(mp.IndexVersion, true, indexblob.DefaultIndexShardSize)
span2.End()
if err != nil {
return errors.Wrap(err, "unable to build pack index")
}
defer closeShards()
// we must hold a lock between writing an index and adding index blob to committed contents index
// otherwise it is possible for concurrent compaction or refresh to forget about the blob we have just
// written
bm.indexesLock.RLock()
defer bm.indexesLock.RUnlock()
indexBlobMDs, err := bm.writeIndexBlobs(ctx, dataShards, bm.currentSessionInfo.ID)
if err != nil {
return errors.Wrap(err, "error writing index blob")
}
if err := bm.commitSession(ctx); err != nil {
return errors.Wrap(err, "unable to commit session")
}
// if we managed to commit the session marker blobs, the index is now fully committed
// and will be visible to others, including blob GC.
for i, indexBlobMD := range indexBlobMDs {
bm.onUpload(int64(dataShards[i].Length()))
if err := bm.addIndexBlob(ctx, indexBlobMD.BlobID, dataShards[i], true); err != nil {
return errors.Wrap(err, "unable to add committed content")
}
}
bm.packIndexBuilder = make(index.Builder)View on GitHub (pinned to 82495e54b5)