kopia/kopia · error
unable to open index blob
Error message
unable to open index blob %q
What it means
After successfully downloading an index blob, addIndexBlobsToBuilder calls index.Open to parse its contents; this error wraps a parse/decode failure. It means the blob exists and was fetched/decrypted, but its bytes are not a valid index blob for the current format (accounting for the encryptor overhead).
Solutions
- Upgrade the Kopia client to match (or exceed) the version that wrote the repository.
- Delete or quarantine the corrupt index blob and re-run compaction so a fresh one is generated from remaining blobs.
- Verify storage integrity (checksums) and restore the blob from a backup or replica.
- Check that the repository's format-blob encryption overhead matches the key being used.
Example fix
// before
ndx, err := index.Open(data.ToByteSlice(), nil, enc.crypter.Encryptor().Overhead)
if err != nil {
return errors.Wrapf(err, "unable to open index blob %q", indexBlobID)
}
// after: skip corrupt blobs instead of failing the whole epoch
ndx, err := index.Open(data.ToByteSlice(), nil, enc.crypter.Encryptor().Overhead)
if err != nil {
return errors.Wrapf(err, "unable to open index blob %q; consider removing this corrupt blob", indexBlobID)
} Defensive patterns
Strategy: validation
Validate before calling
hdr, err := st.GetMetadata(ctx, indexBlobID)
if err == nil && hdr.Length < minValidIndexBlobSize {
return fmt.Errorf("index blob %q suspiciously small (%d bytes); likely corrupt", indexBlobID, hdr.Length)
} Type guard
func validIndexBlob(data []byte) bool {
_, err := index.Open(data, nil, overhead)
return err == nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "unable to open index blob") {
// corrupt or incompatible blob: quarantine it, upgrade client if version mismatch
quarantineBlob(indexBlobID)
} Prevention
- Use matching Kopia versions across all clients touching a repository.
- Enable storage-side checksumming/integrity features to detect bit-rot.
- Keep repository backups so corrupt index blobs can be restored.
- Never interrupt uploads (e.g. kill -9) that write index blobs.
When it happens
Trigger: Compacting when an index blob is corrupt or truncated on disk/storage, was written by an incompatible (newer) index format version, or the encryptor overhead doesn't match how the blob was written.
Common situations: Bit-rot or interrupted upload leaving a truncated blob; opening a repository created by a newer Kopia with an older client; mixing index format versions after a failed upgrade to index blob manager V1.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- invalid entry length
- could not find starting position
- error adding index to builder
- error iterating index entries
- error iterating index entries
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/f666e0b663edb4d0.
Report an issue: GitHub.
Appendix: source
Thrown at repo/content/indexblob/index_blob_manager_v0.go:587
}
}
contentlog.Log1(ctx, m.log, "finished drop-content-deleted-before", logparam.Time("dropDeletedBefore", opt.DropDeletedBefore))
}
}
func addIndexBlobsToBuilder(ctx context.Context, enc *EncryptionManager, addEntry func(index.Info), indexBlobID blob.ID) error {
var data gather.WriteBuffer
defer data.Close()
err := enc.GetEncryptedBlob(ctx, indexBlobID, &data)
if err != nil {
return errors.Wrapf(err, "error getting index %q", indexBlobID)
}
ndx, err := index.Open(data.ToByteSlice(), nil, enc.crypter.Encryptor().Overhead)
if err != nil {
return errors.Wrapf(err, "unable to open index blob %q", indexBlobID)
}
_ = ndx.Iterate(index.AllIDs, func(i index.Info) error {
addEntry(i)
return nil
})
return nil
}
func blobsOlderThan(m []blob.Metadata, cutoffTime time.Time) []blob.Metadata {
var res []blob.Metadata
for _, m := range m {
if !m.Timestamp.After(cutoffTime) {
res = append(res, m)
}
}View on GitHub (pinned to 82495e54b5)