nats-io/nats-server · error

received unknown packet type %d

Error message

received unknown packet type %d

What it means

After CONNECT, the MQTT read loop dispatches packets by their 4-bit type in the fixed header's high nibble (pt>>4). If the type does not match any known MQTT control packet handled by the switch, this error is produced and the connection is dropped. It signals a corrupt or malicious/non-conformant client stream.

Source

Thrown at server/mqtt.go:989

			}

		case mqttPacketDisconnect:
			if trace {
				c.traceInOp("DISCONNECT", nil)
			}
			// Normal disconnect, we need to discard the will.
			// Spec [MQTT-3.1.2-8]
			c.mu.Lock()
			if c.mqtt.cp != nil {
				c.mqtt.cp.will = nil
			}
			c.mu.Unlock()
			s.mqttHandleClosedClient(c)
			c.closeConnection(ClientClosed)
			return nil

		default:
			err = fmt.Errorf("received unknown packet type %d", pt>>4)
		}
	}
	if err == nil && rd > 0 {
		r.reader.SetReadDeadline(time.Now().Add(rd))
	}
	return err
}

func mqttCheckFixedHeaderFlags(packetType, flags byte) error {
	var expected byte
	switch packetType {
	case mqttPacketConnect, mqttPacketPubAck, mqttPacketPubRec, mqttPacketPubComp,
		mqttPacketPing, mqttPacketDisconnect:
		expected = 0
	case mqttPacketPubRel, mqttPacketSub, mqttPacketUnsub:
		expected = 0x2
	case mqttPacketPub:
		return nil

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Fix or upgrade the client library so it never emits reserved/unknown packet types.
  2. Inspect the packet trace (enable debug/trace logging) to capture the offending bytes and identify the sender.
  3. Check network path for proxies/terminators that could corrupt framing.
  4. Treat the disconnect as expected server behavior: per MQTT spec, malformed packets justify closing the connection.
Defensive patterns

Strategy: validation

Validate before calling

// Client-side sanity: assert every emitted packet type is a legal MQTT type
const VALID = new Set([1,2,3,4,6,7,8,10,11,12,13,14]);
if (!VALID.has(pt >> 4)) throw new Error(`invalid packet type ${pt >> 4}`);

Type guard

function isKnownMqttPacketType(pt) { const t = pt >> 4; return t >= 1 && t <= 14 && t !== 5 && t !== 9; }

Prevention

When it happens

Trigger: A client sends a packet whose fixed-header type bits (pt>>4) fall outside the handled set (CONNECT, PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, UNSUBSCRIBE, PINGREQ, DISCONNECT). Seen in the default branch of the read-loop switch.

Common situations: Data corruption on the wire; a custom/broken MQTT client implementation; a proxy mangling bytes; protocol-level confusion where reserved packet types (e.g. type 0) are sent; fuzz tests feeding random bytes.

Related errors


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