{"record":{"id":"5abb826483cc005d","repo":"hyperledger/fabric","slug":"error-converting-envelope-to-config-update-s","errorCode":null,"errorMessage":"error converting envelope to config update: %s","messagePattern":"error converting envelope to config update: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/validator.go","lineNumber":139,"sourceCode":"\t\tnamespace:   namespace,\n\t\tpm:          pm,\n\t\tsequence:    config.Sequence,\n\t\tconfigMap:   configMap,\n\t\tchannelID:   channelID,\n\t\tconfigProto: config,\n\t}, nil\n}\n\n// ProposeConfigUpdate takes in an Envelope of type CONFIG_UPDATE and produces a\n// ConfigEnvelope to be used as the Envelope Payload Data of a CONFIG message\nfunc (vi *ValidatorImpl) ProposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigEnvelope, error) {\n\treturn vi.proposeConfigUpdate(configtx)\n}\n\nfunc (vi *ValidatorImpl) proposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigEnvelope, error) {\n\tconfigUpdateEnv, err := protoutil.EnvelopeToConfigUpdate(configtx)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error converting envelope to config update: %s\", err)\n\t}\n\n\tconfigMap, err := vi.authorizeUpdate(configUpdateEnv)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error authorizing update: %s\", err)\n\t}\n\n\tchannelGroup, err := configMapToConfig(configMap, vi.namespace)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"could not turn configMap back to channelGroup: %s\", err)\n\t}\n\n\treturn &cb.ConfigEnvelope{\n\t\tConfig: &cb.Config{\n\t\t\tSequence:     vi.sequence + 1,\n\t\t\tChannelGroup: channelGroup,\n\t\t},\n\t\tLastUpdate: configtx,","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/validator.go#L121-L157","documentation":"This error is returned by ValidatorImpl.proposeConfigUpdate when the submitted envelope cannot be unmarshaled into a ConfigUpdateEnvelope. It means the payload of the config update transaction is malformed or not a valid protobuf envelope, so the validator never even attempts authorization. It is a defensive wrapper (via errors.Errorf with %s) preserving the underlying unmarshal error.","triggerScenarios":"Calling ProposeConfigUpdate with an envelope whose payload is nil, not a marshaled cb.ConfigUpdateEnvelope, truncated/corrupted bytes, or an envelope produced by a different/incompatible proto schema version.","commonSituations":"Clients constructing config update transactions by hand with incorrect marshaling; envelopes that were signed/modified incorrectly; cross-version Fabric SDKs producing proto payloads the orderer cannot parse; submitting an ordinary transaction envelope instead of a config update envelope.","solutions":["Verify the envelope payload unmarshals to cb.ConfigUpdateEnvelope (check protoutil.EnvelopeToConfigUpdate on the input before submitting).","Regenerate the envelope with a matching Fabric proto library / SDK version compatible with the orderer.","Ensure the envelope is built from a proper config update (e.g., configtxlator or channel.Update call), not an arbitrary transaction.","Log the underlying %s cause to pinpoint the exact unmarshal failure."],"exampleFix":"// before\ncfgUpdate := &cb.ConfigUpdate{...}\nenv := &cb.Envelope{Payload: nil} // malformed\norderer.ProposeConfigUpdate(env)\n// after\nenv, err := protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG_UPDATE, channelID, signer, cfgUpdate, 0, 0)\nif err != nil { return err }\norderer.ProposeConfigUpdate(env)","handlingStrategy":"validation","validationCode":"if env == nil || len(env.Payload) == 0 { return errors.New(\"empty config update envelope\") }\ncue := &cb.ConfigUpdateEnvelope{}\nif err := proto.Unmarshal(env.Payload, cue); err != nil { return fmt.Errorf(\"payload is not a ConfigUpdateEnvelope: %w\", err) }","typeGuard":"func isValidEnvelope(env *cb.Envelope) bool { return env != nil && len(env.Payload) > 0 }","tryCatchPattern":"result, err := validator.ProposeConfigUpdate(env)\nif err != nil && strings.Contains(err.Error(), \"error converting envelope to config update\") {\n    // rebuild envelope from a proper ConfigUpdate via protoutil.CreateSignedEnvelope\n}","preventionTips":["Always build config update envelopes with protoutil.CreateSignedEnvelope or an SDK channel.Update API, never hand-assemble bytes","Keep SDK/proto versions aligned with the orderer's Fabric version","Never submit a regular transaction envelope to ProposeConfigUpdate","Log the underlying cause before resubmitting"],"tags":["hyperledger-fabric","configtx","protobuf","unmarshal"],"backgroundTag":"protobuf-unmarshal-failed","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"}