hyperledger/fabric · error

decoded size from DecodeVarint is invalid, expected <=8, but

Error message

decoded size from DecodeVarint is invalid, expected <=8, but got %d

What it means

After DecodeVarint reads the size byte of an order-preserving encoded uint64, that size must be in 1..8 (a uint64 is at most 8 bytes). A decoded size of 0 or > 8 means the byte stream is not a valid order-preserving encoding, so this error is returned.

Source

Thrown at common/ledger/util/util.go:66

	encodedBytes := make([]byte, size+1)
	encodedBytes[0] = sizeBytes[0]
	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

  1. Confirm the input came from EncodeOrderPreservingVarUint64 and you're slicing the correct key offset
  2. Hex-dump the leading byte and verify it is a plausible size (0x01–0x08)
  3. Check for data corruption if the same key previously decoded fine; restore from backup/resync
  4. Add a pre-check on bytes[0] <= 8 before calling the decoder

Example fix

// before
v, n, err := util.DecodeOrderPreservingVarUint64(b)
// after
if len(b) == 0 || b[0] == 0 || b[0] > 8 {
	return fmt.Errorf("invalid encoded size byte: %#x", b[0])
}
v, n, err := util.DecodeOrderPreservingVarUint64(b)
Defensive patterns

Strategy: validation

Validate before calling

func validSizeByte(b []byte) bool {
	return len(b) > 0 && b[0] >= 0x01 && b[0] <= 0x08
}

Type guard

func isOrderPreservingEncoded(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(), "expected <=8") {
		log.Errorf("bad size byte %#x — not order-preserving encoded", bytes[0])
	}
	return err
}

Prevention

When it happens

Trigger: Calling DecodeOrderPreservingVarUint64 on a size byte that is 0 or 9..127 — i.e. bytes not produced by EncodeOrderPreservingVarUint64, or decoding at the wrong offset within a composite key so the 'size' byte is actually payload data.

Common situations: Corrupted or hand-edited ledger keys; passing raw varint-encoded values (where 0x09+ prefix bytes differ); test inputs like TestDecodingBadInputBytes; mixing up which portion of a composite key is the encoded number.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/4b54af7949572fb1. Report an issue: GitHub.