hyperledger/fabric · error

malformed signature format

Error message

malformed signature format

What it means

VerifyConsenterSig unmarshals the signature message bytes into the local Signature protobuf. If those bytes do not decode into the expected Signature message, the error wraps the unmarshal failure as 'malformed signature format', indicating corrupted or non-protobuf signature data.

Source

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

	return v.ReqInspector.requestIDFromSigHeader(req.sigHdr)
}

// VerifyConsenterSig verifies consenter signature
func (v *Verifier) VerifyConsenterSig(signature types.Signature, prop types.Proposal) ([]byte, error) {
	id2Identity := v.RuntimeConfig.Load().(RuntimeConfig).ID2Identities

	identity, exists := id2Identity[signature.ID]
	if !exists {
		return nil, errors.Errorf("node with id of %d doesn't exist", signature.ID)
	}

	sig := &Signature{}
	if err := sig.Unmarshal(signature.Msg); err != nil {
		v.Logger.Errorf("Failed unmarshaling signature from %d: %v", signature.ID, err)
		v.Logger.Errorf("Offending signature Msg: %s", base64.StdEncoding.EncodeToString(signature.Msg))
		v.Logger.Errorf("Offending signature Value: %s", base64.StdEncoding.EncodeToString(signature.Value))
		return nil, errors.Wrap(err, "malformed signature format")
	}

	if err := v.verifySignatureIsBoundToProposal(sig, signature.ID, prop); err != nil {
		return nil, err
	}

	expectedMsgToBeSigned := util.ConcatenateBytes(sig.OrdererBlockMetadata, sig.IdentifierHeader, sig.BlockHeader, nil)
	signedData := &protoutil.SignedData{
		Signature: signature.Value,
		Data:      expectedMsgToBeSigned,
		Identity:  identity,
	}

	return nil, v.ConsenterVerifier.Evaluate([]*protoutil.SignedData{signedData})
}

// VerificationSequence returns verification sequence
func (v *Verifier) VerificationSequence() uint64 {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-request the signature from the originating consenter — the payload is likely corrupted
  2. Verify all cluster nodes run compatible fabric/smartbft versions with the same Signature proto
  3. Check any persistence (WAL/proposal store) for corruption and truncate the bad entry
  4. Ensure no intermediary layer transforms signature.Msg before verification

Example fix

// before: sig.Msg re-encoded as base64 string bytes
sig.Msg = []byte(base64.StdEncoding.EncodeToString(raw))
// after: keep raw protobuf bytes
sig.Msg = raw // protobuf-serialized Signature message
Defensive patterns

Strategy: try-catch

Validate before calling

sig := &Signature{}
if err := proto.Unmarshal(signature.Msg, sig); err != nil {
    return fmt.Errorf("pre-check: invalid signature bytes from %d", signature.ID)
}

Type guard

func isWellFormedSignature(msg []byte) bool { s := &Signature{}; return proto.Unmarshal(msg, s) == nil && len(s.Value) > 0 }

Try / catch

identities, err := verifier.VerifyConsenterSig(signature, proposal)
if err != nil && strings.Contains(err.Error(), "malformed signature format") {
    logger.Warnf("dropping corrupted signature from %d", signature.ID)
    return nil
}

Prevention

When it happens

Trigger: signature.Msg passed to VerifyConsenterSig is not a valid protobuf encoding of the Signature message — truncated bytes, wrong serialization, or bytes produced by a different code path/version.

Common situations: Corrupted signature over the network or in a persisted proposal/wal file; a fork/mismatch of the smartbft signature proto between nodes running different versions; middleware re-encoding the message as base64 or JSON instead of raw protobuf.

Understand the failure class

Related errors


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