hyperledger/fabric · error

malformed signature metadata

Error message

malformed signature metadata

What it means

This error is returned by verifySignatureIsBoundToProposal in the SmartBFT verifier when the SIGNATURES entry of a block's metadata cannot be unmarshalled into a cb.Metadata protobuf. It means the raw bytes at cb.BlockMetadataIndex_SIGNATURES are corrupt or were not produced by a Hyperledger Fabric orderer. The error wraps the underlying proto.Unmarshal error.

Source

Thrown at orderer/consensus/smartbft/verifier.go:428

			base64.StdEncoding.EncodeToString(ordererMD.ConsenterMetadata), base64.StdEncoding.EncodeToString(prop.Metadata))
		return errors.Errorf("consenter metadata in OrdererBlockMetadata doesn't match proposal")
	}

	block, err := ProposalToBlock(prop)
	if err != nil {
		v.Logger.Warnf("got malformed proposal: %v", err)
		return err
	}

	// Ensure Metadata slice is of the right size
	if len(block.Metadata.Metadata) != len(cb.BlockMetadataIndex_name) {
		return errors.Errorf("block metadata is of size %d but should be of size %d",
			len(block.Metadata.Metadata), len(cb.BlockMetadataIndex_name))
	}

	signatureMetadata := &cb.Metadata{}
	if err := proto.Unmarshal(block.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES], signatureMetadata); err != nil {
		return errors.Wrap(err, "malformed signature metadata")
	}

	ordererMDFromBlock := &cb.OrdererBlockMetadata{}
	if err := proto.Unmarshal(signatureMetadata.Value, ordererMDFromBlock); err != nil {
		return errors.Wrap(err, "malformed orderer metadata in block")
	}

	// Ensure the block's OrdererBlockMetadata matches the signature.
	if !proto.Equal(ordererMDFromBlock, ordererMD) {
		return errors.Errorf("signature's OrdererBlockMetadata and OrdererBlockMetadata extracted from block do not match")
	}

	return nil
}

type consenterVerifier struct {
	logger        *flogging.FabricLogger
	channel       string

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Regenerate the block from a trusted source (configtxgen / orderer genesis) rather than repairing bytes
  2. Verify ledger storage integrity; restore from backup or re-fetch blocks from other orderers
  3. Check that all orderers run compatible Fabric versions producing the same metadata layout
  4. Log and inspect the wrapped proto error to confirm the exact unmarshal failure

Example fix

// before: trusting bytes read from an external file
md := readBlockFromFile("block.bin")
err := verifier.VerifyConsenterSig(md, sig)
// after: validate metadata before verification
sigMD := &cb.Metadata{}
if err := proto.Unmarshal(md.Metadata[cb.BlockMetadataIndex_SIGNATURES], sigMD); err != nil {
    return fmt.Errorf("skipping corrupt block: %w", err)
}
err = verifier.VerifyConsenterSig(md, sig)
Defensive patterns

Strategy: validation

Validate before calling

if blk == nil || blk.Metadata == nil || len(blk.Metadata.Metadata) <= int(cb.BlockMetadataIndex_SIGNATURES) {
    return errors.New("block lacks SIGNATURES metadata")
}
probe := &cb.Metadata{}
if err := proto.Unmarshal(blk.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES], probe); err != nil {
    return fmt.Errorf("invalid signature metadata: %w", err)
}

Type guard

func hasSignatureMetadata(b *cb.Block) bool {
    return b != nil && b.Metadata != nil && len(b.Metadata.Metadata) > int(cb.BlockMetadataIndex_SIGNATURES)
}

Try / catch

defer func() {
    if r := recover(); r != nil { log.Printf("block verification panicked: %v", r) }
}()
if err := verifier.VerifyConsenterSig(blk, sig); err != nil {
    if strings.Contains(err.Error(), "malformed signature metadata") {
        log.Warnf("corrupt block %d: %v", blk.Header.Number, err)
        return errSkipBlock
    }
    return err
}

Prevention

When it happens

Trigger: VerifyConsenterSig is called on a block whose Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES] contains bytes that are not a valid serialized cb.Metadata message (truncated, corrupted, or random bytes).

Common situations: Blocks written by non-Fabric or modified tooling; corrupted ledger files after disk issues; manual block surgery during testing; version skew where the metadata layout changed; replaying hand-crafted blocks into the verifier.

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/2b1927720f8a3923. Report an issue: GitHub.