XTLS/Xray-core · error

write encryption response: %w

Error message

write encryption response: %w

What it means

Writing the Encryption Response packet (0x01 with the RSA-encrypted shared secret and verify token) to the underlying connection failed. This is a plain network/socket error on the raw TCP conn, wrapped by writePacket — connection reset, broken pipe, write deadline exceeded, or the peer closed during handshake.

Source

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

		return fmt.Errorf("encrypt shared secret: %w", err)
	}

	verifyToken = append(verifyToken, []byte(c.password)...) // append pre-shared password

	encryptedVerifyToken, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, verifyToken)
	if err != nil {
		return fmt.Errorf("encrypt verify token: %w", err)
	}

	// Send Encryption Response
	err = writePacket(
		c.writer,
		0x01,
		(*Bytes)(&encryptedSharedSecret),
		(*Bytes)(&encryptedVerifyToken),
	)
	if err != nil {
		return fmt.Errorf("write encryption response: %w", err)
	}

	// Enable encryption
	c.reader, err = newCryptoReader(c.reader, sharedSecret)
	if err != nil {
		return fmt.Errorf("new crypto reader: %w", err)
	}

	c.writer, err = newCryptoWriter(c.writer, sharedSecret)
	if err != nil {
		return fmt.Errorf("new crypto writer: %w", err)
	}

	pkt, err = readPacket(c.reader)
	if err != nil {
		return fmt.Errorf("read login finished: %w", err)
	}
	if pkt.packetID == 0x00 {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the wrapped error: io.EOF/reset/timeout tells you whether it is peer-close or deadline
  2. Verify the outbound config points at the real xmc server address and port
  3. Increase or review handshake timeout settings on the underlying connection
  4. Look at server-side logs at that moment — the server may be aborting due to its own key/profile errors
Defensive patterns

Strategy: retry

Try / catch

n, err := conn.Read(buf)
if err != nil {
    if strings.Contains(err.Error(), "write encryption response") {
        return backoff.Retry(dialAndWrap, 3) // transient network cut during handshake
    }
    return err
}

Prevention

When it happens

Trigger: The first Read or Write on the conn returned by WrapConnClient executes the deferred handshake; it fails when the server (or a middlebox) closed the TCP connection between sending the Encryption Request and receiving the response, or the handshake deadline fired (deadlines.beginHandshake).

Common situations: Server rejected the connection at the socket level, NAT/firewall idle teardown, wrong port pointing at a non-xmc service that closed after garbage input, or a handshake timeout that is too tight.

Related errors


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