hyperledger/fabric · error

no signatures in block metadata

Error message

no signatures in block metadata

What it means

BlockSignatureVerifier validates a block's signature metadata. If the block metadata slice does not contain an entry at BlockMetadataIndex_SIGNATURES (metadata too short), there are no signatures to verify, so it fails with this error. It guards against accepting unsigned or structurally invalid blocks.

Source

Thrown at protoutil/blockutils.go:254

	}
}

type VerifierBuilder func(block *cb.Block) BlockVerifierFunc

type BlockVerifierFunc func(header *cb.BlockHeader, metadata *cb.BlockMetadata) error

//go:generate counterfeiter -o mocks/policy.go --fake-name Policy . policy
type policy interface { // copied from common.policies to avoid circular import.
	// EvaluateSignedData takes a set of SignedData and evaluates whether
	// 1) the signatures are valid over the related message
	// 2) the signing identities satisfy the policy
	EvaluateSignedData(signatureSet []*SignedData) error
}

func BlockSignatureVerifier(bftEnabled bool, consenters []*cb.Consenter, policy policy) BlockVerifierFunc {
	return func(header *cb.BlockHeader, metadata *cb.BlockMetadata) error {
		if len(metadata.GetMetadata()) < int(cb.BlockMetadataIndex_SIGNATURES)+1 {
			return errors.Errorf("no signatures in block metadata")
		}

		md := &cb.Metadata{}
		if err := proto.Unmarshal(metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES], md); err != nil {
			return errors.Wrapf(err, "error unmarshalling signatures from metadata: %v", err)
		}

		var signatureSet []*SignedData
		for _, metadataSignature := range md.Signatures {
			var signerIdentity []byte
			var signedPayload []byte
			// if the SignatureHeader is empty and the IdentifierHeader is present, then  the consenter expects us to fetch its identity by its numeric identifier
			if bftEnabled && len(metadataSignature.GetSignatureHeader()) == 0 && len(metadataSignature.GetIdentifierHeader()) > 0 {
				identifierHeader, err := UnmarshalIdentifierHeader(metadataSignature.IdentifierHeader)
				if err != nil {
					return fmt.Errorf("failed unmarshalling identifier header for block %d: %v", header.GetNumber(), err)
				}
				identifier := identifierHeader.GetIdentifier()

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure blocks come from a legitimate ordering service that always writes the SIGNATURES metadata entry
  2. Check block.Metadata length before invoking the verifier and reject early with a clearer message
  3. If building test blocks, populate Metadata[BlockMetadataIndex_SIGNATURES] with a signed cb.Metadata
  4. Confirm BFT/standard ordering metadata index layout matches the verifier configuration (bftEnabled flag)

Example fix

// before
err := verifier(header, metadata)
// after
if len(metadata.GetMetadata()) < int(cb.BlockMetadataIndex_SIGNATURES)+1 {
    return errors.Errorf("block %d: metadata has no SIGNATURES entry", header.GetNumber())
}
err := verifier(header, metadata)
Defensive patterns

Strategy: validation

Validate before calling

func hasSignatureEntry(metadata *cb.BlockMetadata) bool {
    return len(metadata.GetMetadata()) >= int(cb.BlockMetadataIndex_SIGNATURES)+1
}
if !hasSignatureEntry(md) {
    return errors.New("block lacks signature metadata; reject")
}

Type guard

func isSignedBlock(block *cb.Block) bool {
    return len(block.GetMetadata().GetMetadata()) >= int(cb.BlockMetadataIndex_SIGNATURES)+1
}

Try / catch

if err := verifier(header, metadata); err != nil {
    return fmt.Errorf("rejecting block %d: %w", header.GetNumber(), err)
}

Prevention

When it happens

Trigger: Calling the returned BlockVerifierFunc with a cb.BlockMetadata whose Metadata array has fewer entries than BlockMetadataIndex_SIGNATURES+1 — e.g. a genesis-like block, a hand-crafted block, or truncated metadata.

Common situations: Delivering blocks from an untrusted/misbehaving ordering node, testing with manually constructed blocks lacking signatures, or version mismatch where signature metadata is stored at a different index.

Related errors


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