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

  1. Fix the client to send a properly serialized common.Envelope with a valid common.Payload (correct header, marshaled data).
  2. Decode the envelope client-side (e.g. with configtxlator or SDK inspection) to confirm Payload bytes are valid protobuf.
  3. Check SDK/protobuf version compatibility with the orderer's fabric-protos-go-apiv2 and regenerate/update client stubs.
  4. 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

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


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