hyperledger/fabric · error

Unmarshal endorser error: %s

Error message

Unmarshal endorser error: %s

What it means

Each endorsement contains a serialized MSP identity that must be proto-unmarshalable as msp.SerializedIdentity. VSCC's deduplication step rejects the whole transaction if any endorsement's Endorser bytes fail to unmarshal, indicating a malformed or corrupted endorsement.

Source

Thrown at core/handlers/validation/builtin/v12/validation_logic.go:792

	exists = true
	return
}

func (vscc *Validator) deduplicateIdentity(cap *pb.ChaincodeActionPayload) ([]*protoutil.SignedData, error) {
	// this is the first part of the signed message
	prespBytes := cap.Action.ProposalResponsePayload

	// build the signature set for the evaluation
	signatureSet := []*protoutil.SignedData{}
	signatureMap := make(map[string]struct{})
	// loop through each of the endorsements and build the signature set
	for _, endorsement := range cap.Action.Endorsements {
		// unmarshal endorser bytes
		serializedIdentity := &msp.SerializedIdentity{}
		if err := proto.Unmarshal(endorsement.Endorser, serializedIdentity); err != nil {
			logger.Errorf("Unmarshal endorser error: %s", err)
			return nil, policyErr(fmt.Errorf("Unmarshal endorser error: %s", err))
		}
		identity := serializedIdentity.Mspid + string(serializedIdentity.IdBytes)
		if _, ok := signatureMap[identity]; ok {
			// Endorsement with the same identity has already been added
			logger.Warningf("Ignoring duplicated identity, Mspid: %s, pem:\n%s", serializedIdentity.Mspid, serializedIdentity.IdBytes)
			continue
		}
		data := make([]byte, len(prespBytes)+len(endorsement.Endorser))
		copy(data, prespBytes)
		copy(data[len(prespBytes):], endorsement.Endorser)
		signatureSet = append(signatureSet, &protoutil.SignedData{
			// set the data that is signed; concatenation of proposal response bytes and endorser ID
			Data: data,
			// set the identity that signs the message: it's the endorser
			Identity: endorsement.Endorser,
			// set the signature
			Signature: endorsement.Signature,
		})

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Regenerate the transaction with a current, properly configured Fabric SDK so endorsements contain valid serialized identities
  2. Verify MSP configuration on all endorsing peers (valid certs, correct MSP IDs)
  3. Upgrade SDK and peer to compatible versions so protobuf encodings match
Defensive patterns

Strategy: validation

Validate before calling

const id = msp.SerializedIdentity.decode(endorsement.endorser_bytes);
if (!id.mspid || !id.idBytes?.length) {
  throw new Error('Endorsement endorser bytes are not a valid SerializedIdentity');
}

Type guard

function isValidSerializedIdentity(buf) {
  try {
    const id = msp.SerializedIdentity.decode(buf);
    return Boolean(id.mspid) && id.idBytes instanceof Uint8Array && id.idBytes.length > 0;
  } catch { return false; }
}

Try / catch

try {
  await gateway.submit(transaction);
} catch (e) {
  if (String(e).includes('Unmarshal endorser error')) {
    // rebuild the proposal with the official SDK; check MSP config
  }
}

Prevention

When it happens

Trigger: A proposal response endorsement whose Endorser field is not a valid protobuf msp.SerializedIdentity, encountered while building the signature set in deduplicateIdentity during validation.

Common situations: SDK misconfiguration placing non-identity bytes in the endorser field; corrupted proposal responses over the network; custom endorsers producing malformed identities; Fabric version/protobuf incompatibilities between SDK and peers.

Related errors


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