{"record":{"id":"bc1f1f992f2d9ee3","repo":"hyperledger/fabric","slug":"could-not-convert-message-to-signeddata-s","errorCode":null,"errorMessage":"could not convert message to signedData: %s","messagePattern":"could not convert message to signedData: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/msgprocessor/expiration.go","lineNumber":46,"sourceCode":"\treturn &expirationRejectRule{filterSupport: filterSupport}\n}\n\ntype expirationRejectRule struct {\n\tfilterSupport resources\n}\n\n// Apply checks whether the identity that created the envelope has expired\nfunc (exp *expirationRejectRule) Apply(message *common.Envelope) error {\n\tordererConf, ok := exp.filterSupport.OrdererConfig()\n\tif !ok {\n\t\tlogger.Panic(\"Programming error: orderer config not found\")\n\t}\n\tif !ordererConf.Capabilities().ExpirationCheck() {\n\t\treturn nil\n\t}\n\tsignedData, err := protoutil.EnvelopeAsSignedData(message)\n\tif err != nil {\n\t\treturn errors.Errorf(\"could not convert message to signedData: %s\", err)\n\t}\n\texpirationTime := crypto.ExpiresAt(signedData[0].Identity)\n\t// Identity cannot expire, or identity has not expired yet\n\tif expirationTime.IsZero() || time.Now().Before(expirationTime) {\n\t\treturn nil\n\t}\n\treturn errors.New(\"broadcast client identity expired\")\n}\n","sourceCodeStart":28,"sourceCodeEnd":55,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/msgprocessor/expiration.go#L28-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"payload := &common.Payload{}\nif err := proto.Unmarshal(env.Payload, payload); err != nil { return errors.New(\"client bug: envelope payload is not valid protobuf\") }","typeGuard":null,"tryCatchPattern":"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 }","preventionTips":["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"],"tags":["orderer","fabric","envelope","identity","malformed-input"],"backgroundTag":"malformed-envelope","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}