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 err

View on GitHub (pinned to 24529f1404)

Solutions

  1. Set m.Type to a supported value (codec.Request, codec.Response, codec.Error, or codec.Event) before calling Write
  2. For broadcast/publish use codec.Event, which marshals b as a proto.Message and writes it raw
  3. Verify your transport layer is not resetting m.Type when wrapping messages
  4. 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

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


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/444437cce620d313. Report an issue: GitHub.