kopia/kopia · error
invalid key length: for
Error message
invalid key length: %v for %v
What it means
The v2 index header stores the key (content ID) length in a single byte, so it must be greater than 1 and at most maxUInt8 (255). During Finish/build of the index, if the builder's keyLength is still unset it defaults to unknownKeySize; otherwise any value <= 1 or > 255 is rejected with this error, together with the number of indexed contents. This guards against corrupt or inconsistent content ID metadata being serialized.
Solutions
- Inspect which contents have anomalous content ID lengths and remove or repair them before rebuilding the index.
- Verify the hasher/algorithm used — content IDs must be a fixed, sane length (e.g. 22–64 bytes), not empty or > 255.
- Ensure all contents in one index build use the same content-ID format (same key length).
- Check for metadata corruption in the source packs via integrity verification tools.
Defensive patterns
Strategy: validation
Validate before calling
if b2.keyLength != unknownKeySize && (b2.keyLength <= 1 || b2.keyLength > maxUInt8) {
// reject the content set: content IDs have anomalous lengths
} Try / catch
if err := idxBuilder.Finish(w); err != nil && strings.Contains(err.Error(), "invalid key length") {
// inspect content ID lengths; repair or exclude bad contents
} Prevention
- Use a single, standard content ID hasher for all contents.
- Validate content ID lengths at write time (non-empty, <= 255).
- Run integrity verification on source packs before index builds.
- Never mix content-ID formats in one index build.
When it happens
Trigger: Finishing a v2 index build where b2.keyLength was computed from the sorted content IDs as <= 1 or > maxUInt8 — e.g. contents whose IDs are empty/single-character, or a key length that overflowed 255.
Common situations: Corrupted or foreign content metadata in the pack, custom hashers producing non-standard ID lengths, or mixing content formats with wildly different ID sizes into one index build.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid content ID
- invalid prefix, must be empty or a single letter between…
- DownloadBytesPerSecond
- empty key
- epoch advance on count too low
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/13e62e44e0a3013b.
Report an issue: GitHub.
Appendix: source
Thrown at repo/content/index/index_v2.go:506
}, nil
}
// buildV2 writes the pack index to the provided output.
func buildV2(sortedInfos []*Info, output io.Writer) error { //nolint:gocyclo
b2, err := newIndexBuilderV2(sortedInfos)
if err != nil {
return err
}
w := bufio.NewWriter(output)
// prepare extra data to be appended at the end of an index.
extraData := b2.prepareExtraData(sortedInfos)
if b2.keyLength == -1 {
b2.keyLength = unknownKeySize
} else if b2.keyLength <= 1 || b2.keyLength > maxUInt8 {
return errors.Errorf("invalid key length: %v for %v", b2.keyLength, len(sortedInfos))
}
uniqueFormatInfo2IndexLen := len(b2.uniqueFormatInfo2Index)
if uniqueFormatInfo2IndexLen > maxUInt8 {
return errors.Errorf("invalid unique format v2 info index length: %v", uniqueFormatInfo2IndexLen)
}
// write header
header := make([]byte, v2IndexHeaderSize)
header[0] = Version2 // version
header[1] = byte(b2.keyLength) //nolint:gosec // range checked above
binary.BigEndian.PutUint16(header[2:4], uint16(b2.entrySize)) //nolint:gosec
binary.BigEndian.PutUint32(header[4:8], uint32(b2.entryCount)) //nolint:gosec
binary.BigEndian.PutUint32(header[8:12], uint32(len(b2.packID2Index))) //nolint:gosec
header[12] = byte(uniqueFormatInfo2IndexLen)
binary.BigEndian.PutUint32(header[13:17], uint32(b2.baseTimestamp)) //nolint:gosec
if _, err := w.Write(header); err != nil {View on GitHub (pinned to 82495e54b5)