hyperledger/fabric · error
could not convert message to signedData: %s
Error message
could not convert message to signedData: %s
What it means
The expiration check rule (active only when orderer capabilities enable ExpirationCheck) converts the incoming broadcast Envelope to SignedData to inspect the client identity's expiry. If protoutil.EnvelopeAsSignedData fails (typically an unparseable/malformed Payload or bad signature structure), the rule cannot evaluate expiration and returns this error instead of accepting the message.
Source
Thrown at orderer/common/msgprocessor/expiration.go:46
return &expirationRejectRule{filterSupport: filterSupport}
}
type expirationRejectRule struct {
filterSupport resources
}
// Apply checks whether the identity that created the envelope has expired
func (exp *expirationRejectRule) Apply(message *common.Envelope) error {
ordererConf, ok := exp.filterSupport.OrdererConfig()
if !ok {
logger.Panic("Programming error: orderer config not found")
}
if !ordererConf.Capabilities().ExpirationCheck() {
return nil
}
signedData, err := protoutil.EnvelopeAsSignedData(message)
if err != nil {
return errors.Errorf("could not convert message to signedData: %s", err)
}
expirationTime := crypto.ExpiresAt(signedData[0].Identity)
// Identity cannot expire, or identity has not expired yet
if expirationTime.IsZero() || time.Now().Before(expirationTime) {
return nil
}
return errors.New("broadcast client identity expired")
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the client to send a properly serialized common.Envelope with a valid common.Payload (correct header, marshaled data).
- Decode the envelope client-side (e.g. with configtxlator or SDK inspection) to confirm Payload bytes are valid protobuf.
- Check SDK/protobuf version compatibility with the orderer's fabric-protos-go-apiv2 and regenerate/update client stubs.
- Verify no intermediary is altering envelope bytes; re-submit with TLS and intact serialization.
Defensive patterns
Strategy: try-catch
Validate before calling
payload := &common.Payload{}
if err := proto.Unmarshal(env.Payload, payload); err != nil { return errors.New("client bug: envelope payload is not valid protobuf") } Try / catch
if err := broadcast.Send(env); err != nil && strings.Contains(err.Error(), "could not convert message to signedData") { rebuild and re-serialize the envelope client-side } Prevention
- Construct envelopes only through a supported Fabric SDK
- Keep client protobuf libraries aligned with the orderer's (fabric-protos-go-apiv2)
- Verify envelope bytes with configtxlator before submission
- Avoid custom proxies that touch envelope payloads
When it happens
Trigger: msgprocessor (system channel or config processor) Apply is invoked with an Envelope whose Payload cannot be unmarshalled (nil, corrupt, or wrong proto type), so EnvelopeAsSignedData errors and the rule wraps it with this message.
Common situations: Clients sending truncated or non-standard protobuf envelopes (custom SDK bugs); proxy/middleware mangling the payload bytes; envelopes constructed by hand with missing Payload; after a protobuf library migration (fabric-protos-go to -apiv2) with encoding mistakes.
Related errors
- broadcast client identity expired
- missing channel header
- empty block data
- failed extracting envelope from block
- cannot enable channel capabilities without orderer support f
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/bc1f1f992f2d9ee3.
Report an issue: GitHub.