{"record":{"id":"6721d487ea7a82bc","repo":"grpc/grpc-go","slug":"cannot-register-a-nil-codec","errorCode":null,"errorMessage":"cannot register a nil Codec","messagePattern":"cannot register a nil Codec","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"encoding/encoding.go","lineNumber":134,"sourceCode":"var registeredCodecs = make(map[string]any)\n\n// RegisterCodec registers the provided Codec for use with all gRPC clients and\n// servers.\n//\n// The Codec will be stored and looked up by result of its Name() method, which\n// should match the content-subtype of the encoding handled by the Codec.  This\n// is case-insensitive, and is stored and looked up as lowercase.  If the\n// result of calling Name() is an empty string, RegisterCodec will panic. See\n// Content-Type on\n// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for\n// more details.\n//\n// NOTE: this function must only be called during initialization time (i.e. in\n// an init() function), and is not thread-safe.  If multiple Codecs are\n// registered with the same name, the one registered last will take effect.\nfunc RegisterCodec(codec Codec) {\n\tif codec == nil {\n\t\tpanic(\"cannot register a nil Codec\")\n\t}\n\tif codec.Name() == \"\" {\n\t\tpanic(\"cannot register Codec with empty string result for Name()\")\n\t}\n\tcontentSubtype := strings.ToLower(codec.Name())\n\tregisteredCodecs[contentSubtype] = codec\n}\n\n// GetCodec gets a registered Codec by content-subtype, or nil if no Codec is\n// registered for the content-subtype.\n//\n// The content-subtype is expected to be lowercase.\nfunc GetCodec(contentSubtype string) Codec {\n\tc, _ := registeredCodecs[contentSubtype].(Codec)\n\treturn c\n}\n","sourceCodeStart":116,"sourceCodeEnd":151,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/encoding/encoding.go#L116-L151","documentation":"encoding.RegisterCodec (encoding.go:132) registers a Codec for a content-subtype so gRPC can marshal/unmarshal messages. It panics if passed a nil Codec interface because storing nil would later produce nil-pointer dereferences deep in the codec lookup path; failing fast at registration is safer. Must be called from init() (not thread-safe).","triggerScenarios":"Calling encoding.RegisterCodec(nil), most often because a variable holding the codec was never initialized, a build tag left the codec nil, or a constructor returned nil and was passed directly.","commonSituations":"A custom codec struct's package was not imported (so the variable is nil); a codec depending on a build tag (e.g. a GPU/protobuf variant) that wasn't selected; a refactor that replaced the codec value with nil.","solutions":["Find the RegisterCodec call in the panic trace and ensure the codec value is non-nil and fully constructed.","Register codecs in an init() block and verify the package is imported (blank import if needed) so the variable is initialized.","Add a guard: if codec != nil { encoding.RegisterCodec(codec) } if the codec is optional."],"exampleFix":"// before\nvar myCodec encoding.Codec // nil, never assigned\nfunc init() { encoding.RegisterCodec(myCodec) } // panics\n\n// after\nfunc init() {\n    c := &jsonpb.Codec{}\n    encoding.RegisterCodec(c)\n}","handlingStrategy":"validation","validationCode":"// Guard nil before registering at init time\nfunc init() {\n    c := buildCodec()\n    if c == nil {\n        log.Fatal(\"codec is nil; check build tags / imports\")\n    }\n    encoding.RegisterCodec(c)\n}","typeGuard":"func isCodecNil(c encoding.Codec) bool { return c == nil }","tryCatchPattern":null,"preventionTips":["Always construct the codec value explicitly; avoid package-level nil variables passed to RegisterCodec.","Blank-import the package that defines the codec so its init() runs.","Unit-test that RegisterCodec is reached with a populated value."],"tags":["encoding","codec","panic","grpc-go","init"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}