XTLS/Xray-core · error

write login acknowledged: %w

Error message

write login acknowledged: %w

What it means

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.

Source

Thrown at transport/internet/finalmask/xmc/client.go:218

		if readErr := pkt.readFields(&reason); readErr != nil {
			return fmt.Errorf("authentication rejected")
		}
		return fmt.Errorf("authentication rejected: %s", reason)
	}
	if pkt.packetID != 0x02 {
		return fmt.Errorf("bad login finished packet id: %d", pkt.packetID)
	}

	receivedProfile, err := readLoginSuccess(pkt)
	if err != nil {
		return fmt.Errorf("read login finished fields: %w", err)
	}
	if receivedProfile != selectedProfile {
		return fmt.Errorf("login profile mismatch")
	}
	loginAcknowledgedLength, err := writePacketWithLength(c.writer, 0x03)
	if err != nil {
		return fmt.Errorf("write login acknowledged: %w", err)
	}
	if err = runPaddingSchedule(c.reader, c.writer, true, loginAcknowledgedLength, c.paddingSchedule); err != nil {
		return fmt.Errorf("run startup padding: %w", err)
	}

	packet := newPacketStream(c.reader, c.writer, true)
	c.lifecycleMu.Lock()
	if c.closed {
		c.lifecycleMu.Unlock()
		packet.Stop()
		return net.ErrClosed
	}
	c.packet = packet
	c.reader = packet
	c.writer = packet
	c.state = clientStateProxy
	c.lifecycleMu.Unlock()

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check server logs for why it closed right after sending Login Success
  2. Inspect the wrapped error for timeout vs reset; adjust the conn deadline if it is a timeout
  3. Confirm no firewall sits between the endpoints that kills the flow after N bytes/packets
Defensive patterns

Strategy: retry

Try / catch

_, err := conn.Write(buf)
if err != nil {
    var ne net.Error
    if errors.As(err, &ne) && ne.Timeout() && strings.Contains(err.Error(), "login acknowledged") {
        _ = conn.Close()
        return redialWithBackoff()
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: Server-side post-auth abort, NAT/firewall connection tracking expiry on slow links, or an aggressive handshake deadline on the underlying net.Conn.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/be53349c3b1eb8b5. Report an issue: GitHub.