nats-io/nats-server · error

subscribe QoS value must be 0, 1 or 2, got %v

Error message

subscribe QoS value must be 0, 1 or 2, got %v

What it means

MQTT SUBSCRIBE parser guard (spec MQTT-3.8.3-4): the requested QoS byte for a topic filter is greater than 2, which is reserved and invalid. Parsing aborts before the subscriptions are registered.

Source

Thrown at server/mqtt.go:5339

			return 0, nil, err
		}
		var qos byte
		// We are going to report if we had an error during the conversion,
		// but we don't fail the parsing. When processing the sub, we will
		// have an error then, and the processing of subs code will send
		// the proper mqttSubAckFailure flag for this given subscription.
		filter, err := mqttFilterToNATSSubject(topic)
		if err != nil {
			c.Errorf("invalid topic %q: %v", topic, err)
		}
		if sub {
			qos, err = r.readByte("QoS")
			if err != nil {
				return 0, nil, err
			}
			// Spec [MQTT-3-8.3-4].
			if qos > 2 {
				return 0, nil, fmt.Errorf("subscribe QoS value must be 0, 1 or 2, got %v", qos)
			}
		}
		f := &mqttFilter{ttopic: topic, filter: string(filter), qos: qos}
		filters = append(filters, f)
	}
	// Spec [MQTT-3.8.3-3], [MQTT-3.10.3-2]
	if len(filters) == 0 {
		return 0, nil, fmt.Errorf("%ssubscribe protocol must contain at least 1 topic filter", action)
	}
	return pi, filters, nil
}

func mqttSubscribeTrace(pi uint16, filters []*mqttFilter) string {
	var sep string
	sb := &strings.Builder{}
	sb.WriteString("[")
	for i, f := range filters {
		sb.WriteString(sep)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Request QoS 0, 1 or 2 for each topic filter
  2. Fix the SUBSCRIBE packet encoding in the client
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/mqtt.go:5339 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/6d3f53d29018e17d. Report an issue: GitHub.