hyperledger/fabric · error
decoded size (%d) from DecodeVarint is more than available b
Error message
decoded size (%d) from DecodeVarint is more than available bytes (%d)
What it means
The encoded value declares a payload size s, but the available bytes after the size byte are fewer than s. This guards against out-of-range slice reads and means the buffer is truncated or the decode offset is wrong.
Source
Thrown at common/ledger/util/util.go:68
copy(encodedBytes[1:], bytes[startingIndex:])
return encodedBytes
}
// DecodeOrderPreservingVarUint64 decodes the number from the bytes obtained from method 'EncodeOrderPreservingVarUint64'.
// It returns the decoded number, the number of bytes that are consumed in the process, and an error if the input bytes are invalid.
func DecodeOrderPreservingVarUint64(bytes []byte) (uint64, int, error) {
s, numBytes := protowire.ConsumeVarint(bytes)
if numBytes < 0 {
s, numBytes = 0, 0
}
switch {
case numBytes != 1:
return 0, 0, errors.Errorf("number of consumed bytes from DecodeVarint is invalid, expected 1, but got %d", numBytes)
case s > 8:
return 0, 0, errors.Errorf("decoded size from DecodeVarint is invalid, expected <=8, but got %d", s)
case int(s) > len(bytes)-1:
return 0, 0, errors.Errorf("decoded size (%d) from DecodeVarint is more than available bytes (%d)", s, len(bytes)-1)
default:
// no error
size := int(s)
decodedBytes := make([]byte, 8)
copy(decodedBytes[8-size:], bytes[1:size+1])
numBytesConsumed := size + 1
return binary.BigEndian.Uint64(decodedBytes), numBytesConsumed, nil
}
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Slice off the correct prefix so the decoder receives exactly size-byte + payload bytes
- Verify the composite-key layout matches the writer's version (check key schema/version)
- Check ledger data integrity if truncation is unexpected; resync or restore from snapshot
- Add a length assertion (len(bytes)-1 >= bytes[0]) before decoding
Example fix
// before v, _, err := util.DecodeOrderPreservingVarUint64(fullKey) // fullKey has extra prefix // after numPart := fullKey[len(prefix):] // pass only the encoded-number portion v, _, err := util.DecodeOrderPreservingVarUint64(numPart)
Defensive patterns
Strategy: validation
Validate before calling
func hasEnoughBytes(b []byte) bool {
return len(b) > 0 && int(b[0]) <= len(b)-1
} Type guard
func isCompleteEncodedUint64(b []byte) bool {
return len(b) > 0 && b[0] >= 1 && b[0] <= 8 && len(b) >= int(b[0])+1
} Try / catch
v, n, err := util.DecodeOrderPreservingVarUint64(bytes)
if err != nil {
if strings.Contains(err.Error(), "more than available bytes") {
log.Errorf("truncated encoded value: need %d payload bytes, got %d", bytes[0], len(bytes)-1)
}
return err
} Prevention
- Trim composite-key prefixes so the decoder gets the full encoded value
- Verify key schema/version matches the writer before parsing
- Check for corruption/truncation if data was migrated or partially written
- Unit-test round-trip encode/decode on real key layouts
When it happens
Trigger: Calling DecodeOrderPreservingVarUint64 on a truncated slice — e.g. passing the whole composite key where only the numeric suffix should be given, slicing with an off-by-one, or a key corrupted/shortened by an older writer version.
Common situations: Parsing keys returned by an iterator without trimming prefix bytes; upgrading/downgrading between versions with different composite-key layouts; corrupted ledger data after partial writes.
Related errors
- number of consumed bytes from DecodeVarint is invalid, expec
- decoded size from DecodeVarint is invalid, expected <=8, but
- failed to deserialize values
- failed to deserialize values
- failed to deserialize values
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/bcf0aa98aede30b8.
Report an issue: GitHub.