{"record":{"id":"01e900fdba955495","repo":"hyperledger/fabric","slug":"error-marshaling-proto-marshal-called-with-nil","errorCode":null,"errorMessage":"error marshaling: proto: Marshal called with nil","messagePattern":"error marshaling: proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/configtxlator/main.go","lineNumber":147,"sourceCode":"\tmt, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(msgName))\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error encode input\")\n\t}\n\n\tmsgType := reflect.TypeOf(mt.Zero().Interface())\n\n\tif msgType == nil {\n\t\treturn errors.Errorf(\"message of type %s unknown\", msgType)\n\t}\n\tmsg := reflect.New(msgType.Elem()).Interface().(proto.Message)\n\n\terr = protolator.DeepUnmarshalJSON(input, msg)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error decoding input\")\n\t}\n\n\tif msg == nil {\n\t\treturn errors.New(\"error marshaling: proto: Marshal called with nil\")\n\t}\n\tout, err := proto.Marshal(msg)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error marshaling\")\n\t}\n\n\t_, err = output.Write(out)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error writing output\")\n\t}\n\n\treturn nil\n}\n\nfunc decodeProto(msgName string, input, output *os.File) error {\n\tmt, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(msgName))\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error encode input\")","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/cmd/configtxlator/main.go#L129-L165","documentation":"In `encodeProto` (cmd/configtxlator/main.go:147), after successful JSON decoding, `msg` was still nil, so calling `proto.Marshal` would fail with 'proto: Marshal called with nil'. This is a defensive guard inside configtxlator; in practice it is nearly unreachable because DeepUnmarshalJSON would already have failed on a nil message.","triggerScenarios":"Theoretically triggered when the decoded message ends up nil after DeepUnmarshalJSON succeeds — e.g. a degenerate/custom build where the reflect-constructed message is nil. Standard usage of `configtxlator proto_encode` does not hit this.","commonSituations":"Custom or patched configtxlator builds; pathological input where a nil message is constructed; version drift in protolator/proto helpers.","solutions":["Use an official, unmodified configtxlator binary matching your Fabric version.","Verify the input decodes correctly by first running `configtxlator proto_decode` on a known-good .pb to produce valid JSON.","If building from source, ensure reflect.New(msgType.Elem()) produces a non-nil proto.Message."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"out, err := exec.Command(\"configtxlator\", \"proto_encode\", ...).CombinedOutput()\nif err != nil && strings.Contains(string(out), \"Marshal called with nil\") {\n\tlog.Printf(\"configtxlator binary defect suspected; rebuild from official release: %s\", out)\n}","preventionTips":["Use official configtxlator binaries; this guard is effectively unreachable in standard builds.","Rebuild cleanly from matching Fabric source tags if you maintain a custom binary.","Treat occurrences as a tooling bug, not an input problem."],"tags":["hyperledger-fabric","configtxlator","protobuf","nil-message"],"backgroundTag":"proto-marshal-nil-message","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"}