hyperledger/fabric · warning

malformed message

Error message

malformed message

What it means

After locating the chain, OnConsensus unmarshals the request payload into a protos.Message (the SmartBFT consensus message). If proto.Unmarshal fails — the payload is not a valid protobuf Message — the error is wrapped as 'malformed message' and returned; the message is dropped and never delivered to the consensus state machine.

Source

Thrown at orderer/consensus/smartbft/ingress.go:53

}

// Ingress dispatches Submit and Step requests to the designated per chain instances
type Ingress struct {
	Logger        WarningLogger
	ChainSelector ReceiverGetter
}

// OnConsensus notifies the Ingress for a reception of a StepRequest from a given sender on a given channel
func (in *Ingress) OnConsensus(channel string, sender uint64, request *ab.ConsensusRequest) error {
	receiver := in.ChainSelector.ReceiverByChain(channel)
	if receiver == nil {
		in.Logger.Warningf("An attempt to send a consensus request to a non existing channel (%s) was made by %d", channel, sender)
		return errors.Errorf("channel %s doesn't exist", channel)
	}
	msg := &protos.Message{}
	if err := proto.Unmarshal(request.Payload, msg); err != nil {
		in.Logger.Warningf("Malformed message: %v", err)
		return errors.Wrap(err, "malformed message")
	}
	receiver.HandleMessage(sender, msg)
	return nil
}

// OnSubmit notifies the Ingress for a reception of a SubmitRequest from a given sender on a given channel
func (in *Ingress) OnSubmit(channel string, sender uint64, request *ab.SubmitRequest) error {
	receiver := in.ChainSelector.ReceiverByChain(channel)
	if receiver == nil {
		in.Logger.Warningf("An attempt to submit a transaction to a non existing channel (%s) was made by %d", channel, sender)
		return errors.Errorf("channel %s doesn't exist", channel)
	}
	receiver.HandleRequest(sender, protoutil.MarshalOrPanic(request.Payload))
	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Upgrade all ordering nodes to the same fabric version so consensus message schemas match
  2. Check the sender identity in the log and inspect/fix the node sending malformed payloads (it may be misbehaving or corrupted)
  3. Verify senders use the cluster consensus service (Step API) rather than submitting non-consensus payloads to this ingress
  4. If corruption is suspected, restart the offending node and confirm TLS integrity between cluster members
Defensive patterns

Strategy: try-catch

Validate before calling

// Sender-side: verify the payload marshals cleanly before sending
payload, err := proto.Marshal(msg)
if err != nil { return err }
var check protos.Message
if err := proto.Unmarshal(payload, &check); err != nil {
    return fmt.Errorf("refusing to send unparseable consensus message: %w", err)
}

Try / catch

err := ingress.OnConsensus(channel, sender, req)
if err != nil {
    var wrapped string = err.Error()
    if strings.Contains(wrapped, "malformed message") {
        log.Warnf("dropping malformed consensus payload from sender %d on %s", sender, channel)
        return nil // drop; do not forward to consensus
    }
    return err
}

Prevention

When it happens

Trigger: A remote sender transmits a ConsensusRequest whose Payload bytes fail proto unmarshaling into protos.Message — truncated payload, wrong message type wrapped, version mismatch between fabric nodes, or a non-consensus payload sent to the consensus ingress.

Common situations: Mixed fabric versions in a cluster where the consensus message schema differs; a corrupted or misrouted request from a malfunctioning peer; a client/sender incorrectly submitting to the consensus port; network corruption (rare, TLS usually prevents).

Understand the failure class

Related errors


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