kopia/kopia · critical

decrypt

Error message

decrypt

What it means

decryptAndVerify calls the format's Encryptor().Decrypt; any failure is wrapped as "decrypt" and counted as invalid content. Because Kopia uses authenticated encryption, a decrypt error almost always means the payload failed the integrity check (wrong bytes for that IV/content ID) rather than a key mismatch — genuine key mismatches surface earlier when connecting to the repository.

Solutions

  1. Run kopia content verify --all to map out corrupted contents
  2. Check and repair storage (S3 versioning, ZFS/Btrfs scrub, RAID rebuild)
  3. Restore the damaged pack blobs from backups or cloud snapshots
  4. Rebuild the index if entries point at wrong offsets
Defensive patterns

Strategy: try-catch

Try / catch

if err := r.GetContent(ctx, contentID, out); err != nil {
    if strings.Contains(err.Error(), "decrypt: ") {
        // AEAD verification failed: data corrupt or wrong index entry
        reportCorruptContent(contentID, err)
    }
    return err
}

Prevention

When it happens

Trigger: attemptReadPackFileLocalIndex or decryptContentAndVerify reading a pack payload that is corrupted, belongs to a different offset, or was written with a different repository format/key.

Common situations: Bit rot on disk or object store; mixing blobs from different repositories; reading a pack blob that was overwritten or truncated; restored files missing their counterparts.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/9ef0235d68a366c5. Report an issue: GitHub.

Appendix: source

Thrown at repo/content/committed_read_manager.go:350

	}

	t0 := timetrack.StartTimer()

	if err := c.Decompress(output, tmp.Bytes().Reader(), true); err != nil {
		return errors.Wrap(err, "error decompressing")
	}

	sm.decompressedBytes.Observe(int64(tmp.Length()), t0.Elapsed())

	return nil
}

func (sm *SharedManager) decryptAndVerify(encrypted gather.Bytes, iv []byte, output *gather.WriteBuffer) error {
	t0 := timetrack.StartTimer()

	if err := sm.format.Encryptor().Decrypt(encrypted, iv, output); err != nil {
		sm.Stats.foundInvalidContent()
		return errors.Wrap(err, "decrypt")
	}

	sm.decryptedBytes.Observe(int64(encrypted.Length()), t0.Elapsed())
	sm.Stats.foundValidContent()
	sm.Stats.decrypted(output.Length())

	// already verified
	return nil
}

// IndexBlobs returns the list of active index blobs.
func (sm *SharedManager) IndexBlobs(ctx context.Context, includeInactive bool) ([]indexblob.Metadata, error) {
	if includeInactive {
		var result []indexblob.Metadata

		for _, prefix := range allIndexBlobPrefixes {
			blobs, err := blob.ListAllBlobs(ctx, sm.st, prefix)
			if err != nil {

View on GitHub (pinned to 82495e54b5)