{"record":{"id":"afc386de45158141","repo":"nats-io/nats-server","slug":"the-first-packet-should-be-a-connect-v-got-v","errorCode":null,"errorMessage":"the first packet should be a CONNECT (%v), got %v","messagePattern":"the first packet should be a CONNECT \\((.+?)\\), got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":812,"sourceCode":"\n\t\t// Read packet type and flags\n\t\tif b, err = r.readByte(\"packet type\"); err != nil {\n\t\t\tbreak\n\t\t}\n\n\t\t// Packet type\n\t\tpt := b & mqttPacketMask\n\n\t\t// If client was not connected yet, the first packet must be\n\t\t// a mqttPacketConnect otherwise we fail the connection.\n\t\tif !connected && pt != mqttPacketConnect {\n\t\t\t// If the buffer indicates that it may be a websocket handshake\n\t\t\t// but the client is not websocket, it means that the client\n\t\t\t// connected to the MQTT port instead of the Websocket port.\n\t\t\tif bytes.HasPrefix(buf, []byte(\"GET \")) && !c.isWebsocket() {\n\t\t\t\terr = errMQTTNotWebsocketPort\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"the first packet should be a CONNECT (%v), got %v\", mqttPacketConnect, pt)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif err = mqttCheckFixedHeaderFlags(pt, b&mqttPacketFlagMask); err != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tmaxLen := int32(jwt.NoLimit)\n\t\tif !connected {\n\t\t\tmaxLen = atomic.LoadInt32(&c.mpay)\n\t\t}\n\t\tpl, complete, err = r.readPacketLen(maxLen)\n\t\tif err != nil || !complete {\n\t\t\tif err == ErrMaxPayload {\n\t\t\t\tc.maxPayloadViolation(pl, maxLen)\n\t\t\t}\n\t\t\tbreak\n\t\t}","sourceCodeStart":794,"sourceCodeEnd":830,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L794-L830","documentation":"The NATS MQTT client-read loop requires the very first MQTT packet on a plain connection to be a CONNECT (packet type 1, mqttPacketConnect). This error is raised when the first received packet is some other MQTT packet type. A special-case sibling error (errMQTTNotWebsocketPort) is returned when the payload looks like an HTTP GET, meaning the client dialed the MQTT port with an HTTP/Websocket request.","triggerScenarios":"A TCP client connects to the MQTT listener (default :1883) and sends a non-CONNECT packet first (e.g. PINGREQ, SUBSCRIBE, or garbage bytes), or sends an HTTP 'GET ' request to the MQTT port instead of the Websocket port. Detected in mqttCheckFixedHeaderFlags/read loop parsing the first packet type.","commonSituations":"Pointing an HTTP client, health-check probe, or browser at the MQTT port; a load balancer sending its own probe bytes; a client library misconfigured with the wrong port/scheme (ws:// vs tcp://); port confusion between 1883 (MQTT) and the websocket listener; fuzzing/robustness testing with arbitrary bytes.","solutions":["Configure the client to open the connection with a CONNECT packet before anything else (do not send PINGREQ/SUBSCRIBE first).","Verify the client targets the MQTT port, not the HTTP monitoring port (:8222) or websocket port; use ws:// only on the websocket listener.","Exclude this port from HTTP health checks or point probes at the monitoring port instead.","Check for intermediaries (proxies, load balancers) injecting bytes before the client's first packet."],"exampleFix":"// before: probe sends HTTP to MQTT port\ncurl http://host:1883/\n\n// after: probe the monitoring port\ncurl http://host:8222/healthz","handlingStrategy":"validation","validationCode":"// Ensure the endpoint is the MQTT port and the client's first action is CONNECT\nconst isMQTTPort = (url.port === '1883' || url.port === '8883') && !url.protocol.startsWith('http');\nif (!isMQTTPort) throw new Error(`Point MQTT client at MQTT port, not ${url}`);","typeGuard":"function isMQTTURL(u) { try { const url = new URL(u); return ['mqtt:','mqtts:','tcp:','tls:'].includes(url.protocol); } catch { return false; } }","tryCatchPattern":null,"preventionTips":["Never point HTTP clients/health probes at the MQTT listener port","Match ws:// URLs only to the websocket listener port","Send CONNECT as the first packet after TCP connect","Beware load balancers injecting probe bytes into raw TCP backends"],"tags":["mqtt","protocol-violation","connection-setup"],"backgroundTag":"invalid-first-packet","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}