geektutu/7days-golang · error

invalid codec type %s

Error message

invalid codec type %s

What it means

NewClient in gee-rpc/day2-client looks up the codec constructor in codec.NewCodecFuncMap by opt.CodecType; if the name is not registered it returns "invalid codec type %s" and refuses to connect. Only codecs registered in NewCodecFuncMap (e.g. Gob "application/gob") are supported.

Source

Thrown at gee-rpc/day2-client/client.go:205

	// if opts is nil or pass nil as parameter
	if len(opts) == 0 || opts[0] == nil {
		return DefaultOption, nil
	}
	if len(opts) != 1 {
		return nil, errors.New("number of options is more than 1")
	}
	opt := opts[0]
	opt.MagicNumber = DefaultOption.MagicNumber
	if opt.CodecType == "" {
		opt.CodecType = DefaultOption.CodecType
	}
	return opt, nil
}

func NewClient(conn net.Conn, opt *Option) (*Client, error) {
	f := codec.NewCodecFuncMap[opt.CodecType]
	if f == nil {
		err := fmt.Errorf("invalid codec type %s", opt.CodecType)
		log.Println("rpc client: codec error:", err)
		return nil, err
	}
	// send options with server
	if err := json.NewEncoder(conn).Encode(opt); err != nil {
		log.Println("rpc client: options error: ", err)
		_ = conn.Close()
		return nil, err
	}
	return newClientCodec(f(conn), opt), nil
}

func newClientCodec(cc codec.Codec, opt *Option) *Client {
	client := &Client{
		seq:     1, // seq starts with 1, 0 means invalid call
		cc:      cc,
		opt:     opt,
		pending: make(map[uint64]*Call),

View on GitHub (pinned to cf36443821)

Solutions

  1. Set opt.CodecType to a registered type such as codec.GobType, or leave it empty to use the default
  2. Use geerpc.DefaultOption or omit the *Option argument to Dial
  3. If a custom codec is needed, register it in codec.NewCodecFuncMap under the exact CodecType string on both client and server
  4. Print codec.NewCodecFuncMap keys to confirm the exact accepted name

Example fix

// before
opt := &geerpc.Option{CodecType: "json"}
client, err := geerpc.Dial("tcp", "localhost:9000", opt)
// after
opt := &geerpc.Option{CodecType: codec.GobType} // "application/gob"
client, err := geerpc.Dial("tcp", "localhost:9000", opt)
Defensive patterns

Strategy: validation

Validate before calling

if _, ok := codec.NewCodecFuncMap[opt.CodecType]; !ok {
	return fmt.Errorf("codec %q not registered; use codec.GobType", opt.CodecType)
}
client, err := geerpc.Dial("tcp", addr, opt)

Type guard

func codecSupported(t string) bool {
	_, ok := codec.NewCodecFuncMap[t]
	return ok
}

Try / catch

client, err := geerpc.Dial("tcp", addr, opt)
if err != nil {
	if strings.Contains(err.Error(), "invalid codec type") {
		opt.CodecType = codec.GobType // fall back to default codec
		client, err = geerpc.Dial("tcp", addr, opt)
	}
	if err != nil { return err }
}

Prevention

When it happens

Trigger: Dial(addr, opt) / NewClient(conn, opt) is called with an Option whose CodecType is a non-empty string that is not a registered key, e.g. opt.CodecType = "json" when no JSON codec was registered on the client side.

Common situations: Copy-pasting an Option with a made-up CodecType; server registers a custom codec type but the client build does not; typo like "gob" vs "application/gob"; forgetting that parseOptions only defaults CodecType when it is empty, not when it is wrong.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/c9886f76b3363d80. Report an issue: GitHub.