hyperledger/fabric · error
bad message: %s
Error message
bad message: %s
What it means
Returned by Chain.ordered when the submitted message cannot be classified as a normal or config transaction — c.isConfig failed to process the payload. The inner error explains why the envelope was rejected (invalid structure, failed validation, unreadable channel header).
Source
Thrown at orderer/consensus/etcdraft/chain.go:927
c.raftMetadataLock.Unlock()
c.support.WriteBlock(block, m)
}
// Orders the envelope in the `msg` content. SubmitRequest.
// Returns
//
// -- batches [][]*common.Envelope; the batches cut,
// -- pending bool; if there are envelopes pending to be ordered,
// -- err error; the error encountered, if any.
//
// It takes care of config messages as well as the revalidation of messages if the config sequence has advanced.
func (c *Chain) ordered(msg *orderer.SubmitRequest) (batches [][]*common.Envelope, pending bool, err error) {
seq := c.support.Sequence()
isconfig, err := c.isConfig(msg.GetPayload())
if err != nil {
return nil, false, errors.Errorf("bad message: %s", err)
}
if isconfig {
// ConfigMsg
if msg.GetLastValidationSeq() < seq {
c.logger.Warnf("Config message was validated against %d, although current config seq has advanced (%d)", msg.GetLastValidationSeq(), seq)
msg.Payload, _, err = c.support.ProcessConfigMsg(msg.GetPayload())
if err != nil {
c.Metrics.ProposalFailures.Add(1)
return nil, true, errors.Errorf("bad config message: %s", err)
}
}
if c.checkForEvictionNCertRotation(msg.GetPayload()) {
if !atomic.CompareAndSwapUint32(&c.leadershipTransferInProgress, 0, 1) {
c.logger.Warnf("A reconfiguration transaction is already in progress, ignoring a subsequent transaction")
returnView on GitHub (pinned to 2736b63f8f)
Solutions
- Read the wrapped inner error (%s) to see the exact validation failure.
- Regenerate the transaction with a supported SDK and correct channel name.
- Validate the envelope with 'configtxlator proto_decode' or peer sign/verify tooling.
- Ensure the client targets a channel this orderer actually serves.
Defensive patterns
Strategy: retry
Try / catch
var timeoutErr *OrdererTimeoutError
if errors.As(err, &timeoutErr) || strings.Contains(err.Error(), "timed out") {
return submitWithBackoff(req)
} Prevention
- Size RPCTimeout for your network RTT.
- Keep orderer-to-orderer latency low.
- Load-balance submits across orderers.
- Alert on leader resource saturation.
When it happens
Trigger: Submitting an envelope whose payload cannot be processed by the message validation path — malformed envelope, wrong channel, invalid marshaled Payload, or a ProcessNormalMsg/ProcessConfigMsg error during classification.
Common situations: Client SDK building envelopes with the wrong proto structure; sending a transaction to the wrong channel; corrupted or hand-crafted envelopes; SDK/client version incompatibility with the channel's config format.
Related errors
- bad config message: %s
- not a config block
- '%s' not equal <newest|oldest|config|(number)>
- unmarshalling block: %s
- specified --channelID %s does not match channel ID %s in con
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/43de0752f3773768.
Report an issue: GitHub.