hyperledger/fabric · error

err

Error message

err

What it means

GetLastConfigIndexFromBlockOrPanic is a convenience wrapper that calls GetLastConfigIndexFromBlock and panics on any error. The bare message "err" is simply the underlying error (unmarshalling failure or missing metadata) propagated as a panic. It indicates the block's last-config metadata could not be parsed or is absent.

Source

Thrown at protoutil/blockutils.go:215

			return 0, errors.Wrap(err, "error unmarshalling LastConfig")
		}
		return lc.Index, nil
	}

	obm := &cb.OrdererBlockMetadata{}
	err = proto.Unmarshal(m.Value, obm)
	if err != nil {
		return 0, errors.Wrap(err, "failed to unmarshal orderer block metadata")
	}
	return obm.LastConfig.Index, nil
}

// GetLastConfigIndexFromBlockOrPanic retrieves the index of the last config
// block as encoded in the block metadata, or panics on error
func GetLastConfigIndexFromBlockOrPanic(block *cb.Block) uint64 {
	index, err := GetLastConfigIndexFromBlock(block)
	if err != nil {
		panic(err)
	}
	return index
}

// CopyBlockMetadata copies metadata from one block into another
func CopyBlockMetadata(src *cb.Block, dst *cb.Block) {
	dst.Metadata = src.Metadata
	// Once copied initialize with rest of the
	// required metadata positions.
	InitBlockMetadata(dst)
}

// InitBlockMetadata initializes metadata structure
func InitBlockMetadata(block *cb.Block) {
	if block.Metadata == nil {
		block.Metadata = &cb.BlockMetadata{Metadata: [][]byte{{}, {}, {}, {}, {}}}
	} else if len(block.Metadata.Metadata) < int(cb.BlockMetadataIndex_COMMIT_HASH+1) {
		for i := len(block.Metadata.Metadata); i <= int(cb.BlockMetadataIndex_COMMIT_HASH); i++ {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Fix the caller to pass a real, valid block (with populated Metadata entries)
  2. Switch to the non-panicking GetLastConfigIndexFromBlock and handle the error explicitly in production paths
  3. Validate block.Metadata length (>= LAST_CONFIG index+1) before calling
  4. Re-fetch the block from the ledger if its data is corrupt

Example fix

// before
index, err := GetLastConfigIndexFromBlock(block)
if err != nil {
    panic(err)
}
// after (caller side)
index, err := GetLastConfigIndexFromBlock(block)
if err != nil {
    return fmt.Errorf("block %d has no readable last-config metadata: %w", block.GetHeader().GetNumber(), err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

func safeLastConfigIndex(block *cb.Block) (uint64, error) {
    if block == nil || block.GetMetadata() == nil {
        return 0, errors.New("block has no metadata")
    }
    return GetLastConfigIndexFromBlock(block)
}

Type guard

func hasReadableLastConfig(block *cb.Block) bool {
    _, err := GetLastConfigIndexFromBlock(block)
    return err == nil
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        logger.Errorf("GetLastConfigIndexFromBlockOrPanic failed: %v", r)
    }
}()

Prevention

When it happens

Trigger: Calling GetLastConfigIndexFromBlockOrPanic with a block whose ORDERER/LAST_CONFIG metadata is missing, empty, or fails to unmarshal as LastConfig/OrdererBlockMetadata — e.g. a non-orderer block or corrupt data.

Common situations: Test code or chaincode/orderer paths passing a synthesized block without metadata, passing a block from a wrong channel type, or corrupt ledger data reaching a code path that assumes validity.

Related errors


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