micro/go-micro · error
unrecognized message type: %v
Error message
unrecognized message type: %v
What it means
protoCodec.Write only serializes messages whose Type is Request, Response, Error, or Event. Any other codec.MessageType on the outgoing message hits the default branch and returns this error. It guards the protobuf-rpc write path against unknown or zero-valued message types.
Source
Thrown at codec/protorpc/protorpc.go:117
return err
}
if flusher, ok := c.rwc.(flusher); ok {
if err = flusher.Flush(); err != nil {
return err
}
}
case codec.Event:
m, ok := b.(proto.Message)
if !ok {
return codec.ErrInvalidMessage
}
data, err := proto.Marshal(m)
if err != nil {
return err
}
_, _ = c.rwc.Write(data)
default:
return fmt.Errorf("unrecognized message type: %v", m.Type)
}
return nil
}
func (c *protoCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error {
c.buf.Reset()
c.mt = mt
switch mt {
case codec.Request:
data, err := ReadNetString(c.rwc)
if err != nil {
return err
}
rtmp := new(Request)
err = proto.Unmarshal(data, rtmp)
if err != nil {
return errView on GitHub (pinned to 24529f1404)
Solutions
- Set m.Type to a supported value (codec.Request, codec.Response, codec.Error, or codec.Event) before calling Write
- For broadcast/publish use codec.Event, which marshals b as a proto.Message and writes it raw
- Verify your transport layer is not resetting m.Type when wrapping messages
- Update go-micro if a new MessageType was added after your pinned version
Example fix
// before
m := &codec.Message{}
c.Write(m, payload) // unrecognized message type: 0
// after
m := &codec.Message{Type: codec.Request}
c.Write(m, payload) Defensive patterns
Strategy: validation
Validate before calling
if m.Type != codec.Request && m.Type != codec.Response && m.Type != codec.Error && m.Type != codec.Event {
return fmt.Errorf("cannot write message type %v via protorpc", m.Type)
} Type guard
func isWritableType(t codec.MessageType) bool {
return t == codec.Request || t == codec.Response || t == codec.Error || t == codec.Event
} Prevention
- Always set Type explicitly when constructing codec.Message
- Use codec.Event for publishes and codec.Request for client calls
- Remember protorpc requires body values implementing proto.Message (else codec.ErrInvalidMessage)
When it happens
Trigger: Calling protoCodec.Write (directly or via a transport) with an m.Type outside {Request, Response, Error, Event}, e.g. the zero value of codec.MessageType or a custom type.
Common situations: Hand-rolled transports or middleware that construct codec.Message structs without setting Type; a newly introduced MessageType not yet handled by protorpc; copying message structs and losing the type field.
Related errors
- failed to marshal: %v is not type of *bytes.Frame or proto.M
- failed to unmarshal: %v is not type of proto.Message
- ErrInvalidMessage
- unknown request path
- unsupported Content-Type
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/444437cce620d313.
Report an issue: GitHub.