{"record":{"id":"be53349c3b1eb8b5","repo":"XTLS/Xray-core","slug":"write-login-acknowledged-w","errorCode":null,"errorMessage":"write login acknowledged: %w","messagePattern":"write login acknowledged: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"transport/internet/finalmask/xmc/client.go","lineNumber":218,"sourceCode":"\t\tif readErr := pkt.readFields(&reason); readErr != nil {\n\t\t\treturn fmt.Errorf(\"authentication rejected\")\n\t\t}\n\t\treturn fmt.Errorf(\"authentication rejected: %s\", reason)\n\t}\n\tif pkt.packetID != 0x02 {\n\t\treturn fmt.Errorf(\"bad login finished packet id: %d\", pkt.packetID)\n\t}\n\n\treceivedProfile, err := readLoginSuccess(pkt)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read login finished fields: %w\", err)\n\t}\n\tif receivedProfile != selectedProfile {\n\t\treturn fmt.Errorf(\"login profile mismatch\")\n\t}\n\tloginAcknowledgedLength, err := writePacketWithLength(c.writer, 0x03)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write login acknowledged: %w\", err)\n\t}\n\tif err = runPaddingSchedule(c.reader, c.writer, true, loginAcknowledgedLength, c.paddingSchedule); err != nil {\n\t\treturn fmt.Errorf(\"run startup padding: %w\", err)\n\t}\n\n\tpacket := newPacketStream(c.reader, c.writer, true)\n\tc.lifecycleMu.Lock()\n\tif c.closed {\n\t\tc.lifecycleMu.Unlock()\n\t\tpacket.Stop()\n\t\treturn net.ErrClosed\n\t}\n\tc.packet = packet\n\tc.reader = packet\n\tc.writer = packet\n\tc.state = clientStateProxy\n\tc.lifecycleMu.Unlock()\n","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/transport/internet/finalmask/xmc/client.go#L200-L236","documentation":"Writing the 0x03 Login Acknowledged packet to the now-encrypted writer failed. This is a socket-level write error (reset, broken pipe, write deadline) on the encrypted stream right after Login Success — the server closed the connection, or the handshake deadline expired before this final write.","triggerScenarios":"First Read/Write on the wrapped conn where the server tears down the TCP session immediately after Login Success (e.g. its own post-login check failed), or the connection was cut by a middlebox at that moment.","commonSituations":"Server-side post-auth abort, NAT/firewall connection tracking expiry on slow links, or an aggressive handshake deadline on the underlying net.Conn.","solutions":["Check server logs for why it closed right after sending Login Success","Inspect the wrapped error for timeout vs reset; adjust the conn deadline if it is a timeout","Confirm no firewall sits between the endpoints that kills the flow after N bytes/packets"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := conn.Write(buf)\nif err != nil {\n    var ne net.Error\n    if errors.As(err, &ne) && ne.Timeout() && strings.Contains(err.Error(), \"login acknowledged\") {\n        _ = conn.Close()\n        return redialWithBackoff()\n    }\n    return err\n}","preventionTips":["Set handshake deadlines that comfortably cover the padding exchange","Monitor server post-login logs to catch aborts right after Login Success","Retry transient first-write failures on a fresh connection"],"tags":["network","handshake","tcp","go"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}