{"record":{"id":"1f152a85d0cee2f4","repo":"hyperledger/fabric","slug":"consenter-options-type-mismatch","errorCode":null,"errorMessage":"consenter options type mismatch","messagePattern":"consenter options type mismatch","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/channelconfig/util.go","lineNumber":337,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"cannot load client cert for consenter %s:%d: %s\", c.GetHost(), c.GetPort(), err)\n\t\t}\n\t\tc.ClientTlsCert = clientCert\n\n\t\tserverCert, err := os.ReadFile(string(c.GetServerTlsCert()))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot load server cert for consenter %s:%d: %s\", c.GetHost(), c.GetPort(), err)\n\t\t}\n\t\tc.ServerTlsCert = serverCert\n\t}\n\treturn proto.Marshal(copyMd)\n}\n\n// MarshalBFTOptions serializes smartbft options.\nfunc MarshalBFTOptions(op *smartbft.Options) ([]byte, error) {\n\tif copyMd, ok := proto.Clone(op).(*smartbft.Options); ok {\n\t\treturn proto.Marshal(copyMd)\n\t} else {\n\t\treturn nil, errors.New(\"consenter options type mismatch\")\n\t}\n}\n","sourceCodeStart":319,"sourceCodeEnd":340,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/channelconfig/util.go#L319-L340","documentation":"MarshalBFTOptions clones the smartbft.Options via proto.Clone and type-asserts the result back to *smartbft.Options; the assertion failing yields this error. With correct proto types the assertion always succeeds, so this indicates op is nil or not actually a *smartbft.Options (wrong concrete type or unregistered proto type). Thrown from the public MarshalBFTOptions, called by NewOrdererGroup.","triggerScenarios":"NewOrdererGroup with BFT orderer type where the options passed as *smartbft.Options are nil or are actually a different proto message type, so proto.Clone returns a clone that fails the *smartbft.Options assertion.","commonSituations":"Mixing smartbft versions/types where the compiled proto type differs from the one asserted; passing nil Options into orderer group creation; custom builds with renamed or vendored smartbft packages producing two distinct Go types.","solutions":["Ensure a non-nil *smartbft.Options with the current fabric-protos smartbft types is passed to NewOrdererGroup / MarshalBFTOptions.","Rebuild with a single consistent version of github.com/hyperledger/fabric-protos-go so there is no vendored duplicate smartbft package.","Check the orderer config selection code path: BFT consensus must populate OrdererConfig with smartbft.Options, not etcdraft or another type's options.","If marshaling manually, verify via reflection that op is *smartbft.Options before calling."],"exampleFix":"// before\nvar op *smartbft.Options // nil\nbytes, err := MarshalBFTOptions(op)\n// after\nop := &smartbft.Options{N: 1, ...}\nbytes, err := MarshalBFTOptions(op)","handlingStrategy":"type-guard","validationCode":"func validBFTOptions(op *smartbft.Options) bool {\n\treturn op != nil\n}\nif !validBFTOptions(op) {\n\treturn errors.New(\"smartbft options must be non-nil\")\n}","typeGuard":"func isSmartBFTOptions(m proto.Message) (*smartbft.Options, bool) {\n\top, ok := m.(*smartbft.Options)\n\tif !ok || op == nil {\n\t\treturn nil, false\n\t}\n\treturn op, true\n}","tryCatchPattern":"// errors are returned, not panicked\nbytes, err := channelconfig.MarshalBFTOptions(op)\nif err != nil {\n\treturn fmt.Errorf(\"marshal smartbft options: %w\", err)\n}","preventionTips":["Pass non-nil *smartbft.Options from the same fabric-protos version the library compiles against","Avoid duplicating/vendoring fabric-protos-go — one type identity per import path","Ensure the BFT orderer config path actually populates smartbft.Options (not another consensus type's options)"],"tags":["hyperledger-fabric","smartbft","proto","type-assertion"],"backgroundTag":"proto-type-mismatch","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"}