grpc/grpc-go · critical

cannot register Codec with empty string result for Name()

Error message

cannot register Codec with empty string result for Name()

What it means

RegisterCodec stores the codec under strings.ToLower(codec.Name()), and that string becomes the content-subtype in the gRPC Content-Type header (e.g. application/grpc+proto). An empty Name() cannot form a valid content-subtype and would be unlook-up-able, so RegisterCodec panics at encoding/encoding.go:136-138 when codec.Name() returns empty. Name() must also be static (identical on every call).

Solutions

  1. Make Name() return a constant non-empty lowercase identifier (e.g. json, proto).
  2. Ensure the value is static across calls and set before the codec is registered.
  3. If the name comes from config, validate it is non-empty at construction and fail loudly before RegisterCodec.

Example fix

// before
func (c flatCodec) Name() string { return c.configuredName } // empty -> panic

// after
func (c flatCodec) Name() string { return "flat" }
Defensive patterns

Strategy: validation

Validate before calling

// Guard before registering a Codec.
func registerSafe(c encoding.Codec) {
    if c == nil || c.Name() == "" {
        log.Printf("skipping registration: invalid codec name")
        return
    }
    encoding.RegisterCodec(c)
}

Prevention

When it happens

Trigger: A Codec whose Name() returns an unset struct field (e.g. `return c.name` where name was never set), a stubbed empty return, or a name computed from an empty env var / config value.

Common situations: Prototyping a codec and leaving Name() stubbed; deriving the name from a flag/ENV/config that is empty in the current environment; copy-pasting a codec and forgetting to rename it.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/b5e8f11a0031ba1e. Report an issue: GitHub.

Appendix: source

Thrown at encoding/encoding.go:137

// servers.
//
// The Codec will be stored and looked up by result of its Name() method, which
// should match the content-subtype of the encoding handled by the Codec.  This
// is case-insensitive, and is stored and looked up as lowercase.  If the
// result of calling Name() is an empty string, RegisterCodec will panic. See
// Content-Type on
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
// more details.
//
// 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 RegisterCodec(codec Codec) {
	if codec == nil {
		panic("cannot register a nil Codec")
	}
	if codec.Name() == "" {
		panic("cannot register Codec with empty string result for Name()")
	}
	contentSubtype := strings.ToLower(codec.Name())
	registeredCodecs[contentSubtype] = codec
}

// GetCodec gets a registered Codec by content-subtype, or nil if no Codec is
// registered for the content-subtype.
//
// The content-subtype is expected to be lowercase.
func GetCodec(contentSubtype string) Codec {
	c, _ := registeredCodecs[contentSubtype].(Codec)
	return c
}

View on GitHub (pinned to 0c51461d27)