{"record":{"id":"3f2525c6348204a2","repo":"nats-io/nats-server","slug":"received-a-second-connect-packet","errorCode":null,"errorMessage":"received a second CONNECT packet","messagePattern":"received a second CONNECT packet","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":228,"sourceCode":"var (\n\tsparkbNamespaceTopicPrefix    = []byte(\"spBv1.0/\")\n\tsparkbCertificatesTopicPrefix = []byte(\"$sparkplug/certificates/\")\n)\n\nvar (\n\tmqttPingResponse     = []byte{mqttPacketPingResp, 0x0}\n\tmqttProtoName        = []byte(\"MQTT\")\n\tmqttOldProtoName     = []byte(\"MQIsdp\")\n\tmqttSessJailDur      = mqttSessFlappingJailDur\n\tmqttFlapCleanItvl    = mqttSessFlappingCleanupInterval\n\tmqttRetainedCacheTTL = mqttDefaultRetainedCacheTTL\n)\n\nvar (\n\terrMQTTNotWebsocketPort           = errors.New(\"MQTT clients over websocket must connect to the Websocket port, not the MQTT port\")\n\terrMQTTTopicFilterCannotBeEmpty   = errors.New(\"topic filter cannot be empty\")\n\terrMQTTMalformedVarInt            = errors.New(\"malformed variable int\")\n\terrMQTTSecondConnectPacket        = errors.New(\"received a second CONNECT packet\")\n\terrMQTTServerNameMustBeSet        = errors.New(\"mqtt requires server name to be explicitly set\")\n\terrMQTTUserMixWithUsersNKeys      = errors.New(\"mqtt authentication username not compatible with presence of users/nkeys\")\n\terrMQTTTokenMixWIthUsersNKeys     = errors.New(\"mqtt authentication token not compatible with presence of users/nkeys\")\n\terrMQTTAckWaitMustBePositive      = errors.New(\"ack wait must be a positive value\")\n\terrMQTTJSAPITimeoutMustBePositive = errors.New(\"JS API timeout must be a positive value\")\n\terrMQTTStandaloneNeedsJetStream   = errors.New(\"mqtt requires JetStream to be enabled if running in standalone mode\")\n\terrMQTTConnFlagReserved           = errors.New(\"connect flags reserved bit not set to 0\")\n\terrMQTTWillAndRetainFlag          = errors.New(\"if Will flag is set to 0, Will Retain flag must be 0 too\")\n\terrMQTTPasswordFlagAndNoUser      = errors.New(\"password flag set but username flag is not\")\n\terrMQTTCIDEmptyNeedsCleanFlag     = errors.New(\"when client ID is empty, clean session flag must be set to 1\")\n\terrMQTTEmptyWillTopic             = errors.New(\"empty Will topic not allowed\")\n\terrMQTTEmptyUsername              = errors.New(\"empty user name not allowed\")\n\terrMQTTTopicIsEmpty               = errors.New(\"topic cannot be empty\")\n\terrMQTTPacketIdentifierIsZero     = errors.New(\"packet identifier cannot be 0\")\n\terrMQTTUnsupportedCharacters      = errors.New(\"character not supported for MQTT topics\")\n\terrMQTTInvalidSession             = errors.New(\"invalid MQTT session\")\n\terrMQTTInvalidRetainFlags         = errors.New(\"invalid retained message flags\")\n\terrMQTTInvalidRetainedMessage     = errors.New(\"invalid retained message\")","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L210-L246","documentation":"Per the MQTT spec [MQTT-3.1.0-2], a client may send the CONNECT packet only once per connection. If a second CONNECT arrives after the session is already established, the server returns `errMQTTSecondConnectPacket` and closes the connection.","triggerScenarios":"A client sending CONNECT twice on one TCP/WS connection (e.g. re-using the connection object after an auto-reconnect that did not reset the socket); buggy reconnect logic that re-sends the handshake on the existing stream (server/mqtt.go:942).","commonSituations":"Custom or embedded MQTT clients with flawed reconnection logic; wrapper libraries double-invoking connect; test scripts replaying captured packets.","solutions":["Fix the client so a reconnect always opens a new TCP/WebSocket connection before sending CONNECT","Ensure connect() is called at most once per established network connection","Upgrade the MQTT client library if its auto-reconnect path resends CONNECT on the same socket"],"exampleFix":"// before: reuse connection on reconnect\nif disconnected { client.sendConnect() }\n// after: establish a fresh connection for each reconnect\nif disconnected { client.dial(); client.sendConnect() }","handlingStrategy":"try-catch","validationCode":"// Guard: never call connect() twice on one connection object\nif (client.state === 'connected') return;","typeGuard":null,"tryCatchPattern":"// On reconnect, always recreate the transport\nclient.on('close', () => setTimeout(() => newConnection().connect(), backoff))","preventionTips":["Reset the socket on every reconnect","Do not replay CONNECT from generic retry wrappers","Add an integration test covering disconnect/reconnect cycles"],"tags":["mqtt","protocol","connect","reconnect"],"backgroundTag":"mqtt-protocol-violation","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}