{"record":{"id":"d081b25cf31a919c","repo":"nats-io/nats-server","slug":"received-unknown-packet-type-d","errorCode":null,"errorMessage":"received unknown packet type %d","messagePattern":"received unknown packet type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":989,"sourceCode":"\t\t\t}\n\n\t\tcase mqttPacketDisconnect:\n\t\t\tif trace {\n\t\t\t\tc.traceInOp(\"DISCONNECT\", nil)\n\t\t\t}\n\t\t\t// Normal disconnect, we need to discard the will.\n\t\t\t// Spec [MQTT-3.1.2-8]\n\t\t\tc.mu.Lock()\n\t\t\tif c.mqtt.cp != nil {\n\t\t\t\tc.mqtt.cp.will = nil\n\t\t\t}\n\t\t\tc.mu.Unlock()\n\t\t\ts.mqttHandleClosedClient(c)\n\t\t\tc.closeConnection(ClientClosed)\n\t\t\treturn nil\n\n\t\tdefault:\n\t\t\terr = fmt.Errorf(\"received unknown packet type %d\", pt>>4)\n\t\t}\n\t}\n\tif err == nil && rd > 0 {\n\t\tr.reader.SetReadDeadline(time.Now().Add(rd))\n\t}\n\treturn err\n}\n\nfunc mqttCheckFixedHeaderFlags(packetType, flags byte) error {\n\tvar expected byte\n\tswitch packetType {\n\tcase mqttPacketConnect, mqttPacketPubAck, mqttPacketPubRec, mqttPacketPubComp,\n\t\tmqttPacketPing, mqttPacketDisconnect:\n\t\texpected = 0\n\tcase mqttPacketPubRel, mqttPacketSub, mqttPacketUnsub:\n\t\texpected = 0x2\n\tcase mqttPacketPub:\n\t\treturn nil","sourceCodeStart":971,"sourceCodeEnd":1007,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L971-L1007","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix or upgrade the client library so it never emits reserved/unknown packet types.","Inspect the packet trace (enable debug/trace logging) to capture the offending bytes and identify the sender.","Check network path for proxies/terminators that could corrupt framing.","Treat the disconnect as expected server behavior: per MQTT spec, malformed packets justify closing the connection."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Client-side sanity: assert every emitted packet type is a legal MQTT type\nconst VALID = new Set([1,2,3,4,6,7,8,10,11,12,13,14]);\nif (!VALID.has(pt >> 4)) throw new Error(`invalid packet type ${pt >> 4}`);","typeGuard":"function isKnownMqttPacketType(pt) { const t = pt >> 4; return t >= 1 && t <= 14 && t !== 5 && t !== 9; }","tryCatchPattern":null,"preventionTips":["Use a maintained MQTT client library rather than hand-rolled framing","Never send reserved packet types (0, 5, 9) or type > 14","Check TLS/proxy paths for corruption","Enable server MQTT trace to capture offending bytes"],"tags":["mqtt","protocol-violation","corrupt-data"],"backgroundTag":"unknown-packet-type","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}