{"record":{"id":"44abd630461f4528","repo":"nats-io/nats-server","slug":"other-session-with-client-id-q-is-in-the-process","errorCode":null,"errorMessage":"other session with client ID %q is in the process of connecting","messagePattern":"other session with client ID %q is in the process of connecting","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":4078,"sourceCode":"\t\t\t// not wait for the CONNACK and sends other protocols, the\n\t\t\t// server would not have a fully setup client and may panic.\n\t\t\tasm.mu.Unlock()\n\t\t\tselect {\n\t\t\tcase <-s.quitCh:\n\t\t\tcase <-time.After(mqttSessJailDur):\n\t\t\t}\n\t\t\tc.closeConnection(DuplicateClientID)\n\t\t\treturn ErrConnectionClosed\n\t\t}\n\t}\n\t// If an existing session is in the process of processing some packet, we can't\n\t// evict the old client just yet. So try again to see if the state clears, but\n\t// if it does not, then we have no choice but to fail the new client instead of\n\t// the old one.\n\tif _, ok := asm.sessLocked[cid]; ok {\n\t\tasm.mu.Unlock()\n\t\tif locked++; locked == 10 {\n\t\t\treturn fmt.Errorf(\"other session with client ID %q is in the process of connecting\", cid)\n\t\t}\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\tgoto CHECK\n\t}\n\n\t// Register this client ID the \"locked\" map for the duration if this function.\n\tasm.sessLocked[cid] = struct{}{}\n\t// And remove it on exit, regardless of error or not.\n\tdefer func() {\n\t\tasm.mu.Lock()\n\t\tdelete(asm.sessLocked, cid)\n\t\tasm.mu.Unlock()\n\t}()\n\n\t// Is the client requesting a clean session or not.\n\tcleanSess := cp.flags&mqttConnFlagCleanSession != 0\n\t// Session present? Assume false, will be set to true only when applicable.\n\tsessp := false","sourceCodeStart":4060,"sourceCodeEnd":4096,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L4060-L4096","documentation":"MQTT session-takeover path: another session with the same client ID is mid-connect (present in the sessLocked map), so the new connection cannot evict it yet. The server retries briefly and, if the lock never clears, fails the new connection instead of the old one.","triggerScenarios":"Thrown at server/mqtt.go:4078 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the connect after the competing connection finishes (or a short backoff)","Use a unique client ID per connection","Ensure the previous client disconnects cleanly before reconnecting with the same ID"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}