grpc/grpc-go · critical
cannot register a nil CodecV2
Error message
cannot register a nil CodecV2
What it means
encoding.RegisterCodecV2 (encoding_v2.go:63) registers a CodecV2 (the newer buffer-pool-aware codec interface). Like RegisterCodec it panics on a nil value to avoid later nil-dereferences. CodecV2 takes precedence over Codec when both share a name. Must be called from init().
Source
Thrown at encoding/encoding_v2.go:65
// servers.
//
// The CodecV2 will be stored and looked up by result of its Name() method, which
// should match the content-subtype of the encoding handled by the CodecV2. This
// is case-insensitive, and is stored and looked up as lowercase. If the
// result of calling Name() is an empty string, RegisterCodecV2 will panic. See
// Content-Type on
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
// more details.
//
// If both a Codec and CodecV2 are registered with the same name, the CodecV2
// will be used.
//
// NOTE: this function must only be called during initialization time (i.e. in
// an init() function), and is not thread-safe. If multiple Codecs are
// registered with the same name, the one registered last will take effect.
func RegisterCodecV2(codec CodecV2) {
if codec == nil {
panic("cannot register a nil CodecV2")
}
if codec.Name() == "" {
panic("cannot register CodecV2 with empty string result for Name()")
}
contentSubtype := strings.ToLower(codec.Name())
registeredCodecs[contentSubtype] = codec
}
// GetCodecV2 gets a registered CodecV2 by content-subtype, or nil if no CodecV2 is
// registered for the content-subtype.
//
// The content-subtype is expected to be lowercase.
func GetCodecV2(contentSubtype string) CodecV2 {
c, _ := registeredCodecs[contentSubtype].(CodecV2)
return c
}
View on GitHub (pinned to 03255a9237)
Solutions
- Locate the RegisterCodecV2 call and ensure the value is a fully-constructed non-nil CodecV2.
- Keep registration inside init() and confirm the defining package is imported.
- Guard optional registration: if c != nil { encoding.RegisterCodecV2(c) }.
Example fix
// before
var c2 encoding.CodecV2 // nil
func init() { encoding.RegisterCodecV2(c2) } // panics
// after
func init() { encoding.RegisterCodecV2(&protobuf.NewCodec()) } Defensive patterns
Strategy: validation
Validate before calling
func init() {
c := buildCodecV2()
if c == nil {
log.Fatal("codecv2 is nil")
}
encoding.RegisterCodecV2(c)
} Type guard
func isCodecV2Nil(c encoding.CodecV2) bool { return c == nil } Prevention
- Construct CodecV2 explicitly; never register an uninitialized package-level variable.
- Confirm the defining package is imported so init() runs.
- Guard optional registration with a nil check.
When it happens
Trigger: Calling encoding.RegisterCodecV2(nil) because the CodecV2 value was never assigned or a constructor returned nil.
Common situations: Upgrading a codec to the V2 interface but the package variable holding it is still nil; a build-tag-gated codec whose tag wasn't enabled; a refactor that removed the assignment.
Related errors
- cannot register CodecV2 with empty string result for Name()
- cannot register a nil Codec
- cannot register Codec with empty string result for Name()
- grpc: invalid gzip compression level: %d
- proto: failed to marshal, message is %T, want proto.Message
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/ba147ffa7cc70a1d.
Report an issue: GitHub.