hyperledger/fabric · error

error unmarshalling metadata at index [%s]

Error message

error unmarshalling metadata at index [%s]

What it means

The bytes at the requested metadata index exist but failed to unmarshal into cb.Metadata. The error wraps the proto error, indicating the stored bytes for that index are corrupt or not the expected message type.

Source

Thrown at protoutil/blockutils.go:137

	}

	return chdr.ChannelId, nil
}

// GetMetadataFromBlock retrieves metadata at the specified index.
func GetMetadataFromBlock(block *cb.Block, index cb.BlockMetadataIndex) (*cb.Metadata, error) {
	if block.Metadata == nil {
		return nil, errors.New("no metadata in block")
	}

	if len(block.Metadata.Metadata) <= int(index) {
		return nil, errors.Errorf("no metadata at index [%s]", index)
	}

	md := &cb.Metadata{}
	err := proto.Unmarshal(block.Metadata.Metadata[index], md)
	if err != nil {
		return nil, errors.Wrapf(err, "error unmarshalling metadata at index [%s]", index)
	}
	return md, nil
}

// GetMetadataFromBlockOrPanic retrieves metadata at the specified index, or
// panics on error
func GetMetadataFromBlockOrPanic(block *cb.Block, index cb.BlockMetadataIndex) *cb.Metadata {
	md, err := GetMetadataFromBlock(block, index)
	if err != nil {
		panic(err)
	}
	return md
}

// GetConsenterMetadataFromBlock attempts to retrieve consenter metadata from the value
// stored in block metadata at index SIGNATURES (first field). If no consenter metadata
// is found there, it falls back to index ORDERER (third field).
func GetConsenterMetadataFromBlock(block *cb.Block) (*cb.Metadata, error) {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify ledger integrity and restore the block from another orderer or backup
  2. Log the wrapped proto error to pinpoint the corruption (wrong wire type, truncated message)
  3. Fix any custom block-building code to proto.Marshal a cb.Metadata into the index slot
  4. If corruption is recurring, check storage hardware and Fabric version compatibility

Example fix

// before
raw := readRawMetadataFromStore(idx)
blk.Metadata.Metadata[idx] = raw // arbitrary bytes
// after
md := &cb.Metadata{Value: val}
blk.Metadata.Metadata[idx] = protoMarshal(md) // guaranteed cb.Metadata wire format
Defensive patterns

Strategy: try-catch

Validate before calling

raw := blk.Metadata.Metadata[idx]
probe := &cb.Metadata{}
if err := proto.Unmarshal(raw, probe); err != nil {
    return fmt.Errorf("pre-check: metadata at index %v is corrupt: %w", idx, err)
}

Type guard

func isParsableMetadata(raw []byte) bool {
    md := &cb.Metadata{}
    return proto.Unmarshal(raw, md) == nil
}

Try / catch

md, err := protoutil.GetMetadataFromBlock(blk, idx)
if err != nil {
    if strings.Contains(err.Error(), "error unmarshalling metadata") {
        log.Errorf("corrupt metadata at index %v in block %d: %v", idx, blk.Header.Number, err)
        return restoreBlockFromBackup(blk.Header.Number)
    }
    return err
}

Prevention

When it happens

Trigger: GetMetadataFromBlock's proto.Unmarshal(block.Metadata.Metadata[index], md) fails — bytes truncated, wrong message type stored, or bit-rotted data at that index.

Common situations: Corrupted block store files; custom block producers writing non-cb.Metadata bytes; mixing binary formats across Fabric versions; failing disks or truncated snapshots.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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