kopia/kopia · error

unsupported - too many index v2 format infos

Error message

unsupported - too many index v2 format infos

What it means

Index v2 assigns each distinct content-format info (compression/encryption tuple) a one-byte ID, so at most maxUInt8 (255) distinct format infos are supported. When building a v2 index with more than 255 distinct format infos, this error is returned. It is an explicit format-capacity limit, not data corruption.

Solutions

  1. Reduce the number of distinct compression/encryption formats (rewrite content with a single compressor/encryption scheme).
  2. Split/reorganize content into multiple indexes so each stays under 255 format infos.
  3. Use a newer index format version with a larger format-info capacity if available.

Example fix

// before
// one giant index built over content using 300 distinct compressor/key combos
idx := v2Builder.Build()
// after
// rewrite content with a single compressor, then build
rewriteWithCompressor(ctx, compression.HeaderZstd)
idx := v2Builder.Build()
Defensive patterns

Strategy: validation

Validate before calling

// Go: count distinct format infos before building a v2 index
func tooManyFormatInfos(infos []content.Info, max uint8) bool {
	seen := map[indexV2FormatInfo]struct{}{}
	for _, v := range infos {
		seen[indexV2FormatInfoFromInfo(v)] = struct{}{}
		if len(seen) > int(max) {
			return true
		}
	}
	return false
}

Try / catch

idx, err := buildV2Index(ctx, contents)
if err != nil && strings.Contains(err.Error(), "too many index v2 format infos") {
	// split into multiple indexes or rewrite with fewer formats
}

Prevention

When it happens

Trigger: Building an index v2 where the number of distinct indexV2FormatInfo values (distinct combinations of compression header ID and encryption key ID across entries) exceeds 255 during buildV2.

Common situations: Repositories that historically used many different compressors/encryption keys, accumulating hundreds of distinct format combinations in content info; long-lived repos migrated across many compressor settings.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at repo/content/index/index_v2.go:394

func indexV2FormatInfoFromInfo(v *Info) indexV2FormatInfo {
	return indexV2FormatInfo{
		formatVersion:       v.FormatVersion,
		compressionHeaderID: v.CompressionHeaderID,
		encryptionKeyID:     v.EncryptionKeyID,
	}
}

// buildUniqueFormatToIndexMap builds a map of unique indexV2FormatInfo to their numeric identifiers.
func buildUniqueFormatToIndexMap(sortedInfos []*Info) (map[indexV2FormatInfo]byte, error) {
	result := map[indexV2FormatInfo]byte{}

	for _, v := range sortedInfos {
		key := indexV2FormatInfoFromInfo(v)
		if _, ok := result[key]; !ok {
			rl := len(result)

			if rl > maxUInt8 {
				return nil, errors.New("unsupported - too many index v2 format infos")
			}

			result[key] = byte(rl)
		}
	}

	return result, nil
}

// buildPackIDToIndexMap builds a map of unique blob IDs to their numeric identifiers.
func buildPackIDToIndexMap(sortedInfos []*Info) map[blob.ID]int {
	result := map[blob.ID]int{}

	for _, v := range sortedInfos {
		blobID := v.PackBlobID
		if _, ok := result[blobID]; !ok {
			result[blobID] = len(result)
		}

View on GitHub (pinned to 82495e54b5)