hyperledger/fabric · error
envelope index out of bounds
Error message
envelope index out of bounds
What it means
ExtractEnvelope returns this error when the requested index is negative or >= the number of envelopes in block.Data.Data, i.e. the caller asked for a transaction slot that does not exist in the block. Each block only carries envelopeCount entries.
Source
Thrown at protoutil/commonutils.go:102
// and unmarshals it -- it panics if either of these operations fail
func ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope {
envelope, err := ExtractEnvelope(block, index)
if err != nil {
panic(err)
}
return envelope
}
// ExtractEnvelope retrieves the requested envelope from a given block and
// unmarshals it
func ExtractEnvelope(block *cb.Block, index int) (*cb.Envelope, error) {
if block.Data == nil {
return nil, errors.New("block data is nil")
}
envelopeCount := len(block.Data.Data)
if index < 0 || index >= envelopeCount {
return nil, errors.New("envelope index out of bounds")
}
marshaledEnvelope := block.Data.Data[index]
envelope, err := GetEnvelopeFromBlock(marshaledEnvelope)
err = errors.WithMessagef(err, "block data does not carry an envelope at index %d", index)
return envelope, err
}
// MakeChannelHeader creates a ChannelHeader.
func MakeChannelHeader(headerType cb.HeaderType, version int32, chainID string, epoch uint64) *cb.ChannelHeader {
tm := timestamppb.Now()
tm.Nanos = 0
return &cb.ChannelHeader{
Type: int32(headerType),
Version: version,
Timestamp: tm,
ChannelId: chainID,
Epoch: epoch,
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Bound your loop with len(block.Data.Data) rather than a fixed tx count or block batch size.
- Check the index source: tx validation codes/txids indexes must be recomputed if they reference indices beyond the block.
- Use GetTransactionByID/ledger index APIs instead of hand-tracking envelope indices.
- For a zero-transaction block, handle envelopeCount == 0 explicitly before extracting.
Example fix
// before
for i := 0; i < blockSize; i++ { // blockSize from config, may exceed actual
env, err := protoutil.ExtractEnvelope(block, i)
}
// after
for i := 0; i < len(block.Data.Data); i++ {
env, err := protoutil.ExtractEnvelope(block, i)
} Defensive patterns
Strategy: validation
Validate before calling
func envelopeCount(block *cb.Block) int {
if block == nil || block.Data == nil {
return 0
}
return len(block.Data.Data)
}
// before extracting: if index < 0 || index >= envelopeCount(block) { skip } Type guard
func validEnvelopeIndex(block *cb.Block, index int) bool {
return block != nil && block.Data != nil && index >= 0 && index < len(block.Data.Data)
} Try / catch
env, err := protoutil.ExtractEnvelope(block, i)
if err != nil {
if strings.Contains(err.Error(), "envelope index out of bounds") {
logger.Warnf("block %d: index %d out of bounds (%d txs); truncating iteration",
block.GetHeader().GetNumber(), i, len(block.Data.GetData()))
break
}
return err
} Prevention
- Iterate with len(block.Data.Data), never a configured batch size or assumed tx count
- Handle empty blocks (0 envelopes) explicitly before extraction
- Recompute tx validation/index metadata if stored indices drift from block contents
- Prefer ledger APIs (GetTransactionByID) over manual envelope indexing
When it happens
Trigger: Calling ExtractEnvelope(block, index) with index < 0 or index >= len(block.Data.Data) — typically iterating with a wrong bound, assuming a fixed number of txs per block, or using an index from another block.
Common situations: Block iteration code using the configured batch size instead of len(block.Data.Data); validators/committers re-processing a block after metadata mismatch; tests passing index 0 on an empty block; duplicated-tx lookup (TestBlockfileMgrGetTxByIdDuplicateTxid) with stale indices.
Related errors
- block data is nil
- malformed org definition for org: %s
- organization %s not found
- error encode input
- message of type %s unknown
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3b42421e2ff7bae6.
Report an issue: GitHub.