XTLS/Xray-core · error

new crypto reader: %w

Error message

new crypto reader: %w

What it means

Constructing the AES-CFB crypto reader over the shared secret failed (newCryptoReader wraps the handshake reader with symmetric encryption). In this codebase the constructor derives an AES cipher from the 16-byte sharedSecret, so it only fails if the key length is not a valid AES size — which cannot happen since sharedSecret is hardcoded to 16 bytes. In practice this error is a defensive guard that is not expected to fire.

Source

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

	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 {
		var reason String
		if readErr := pkt.readFields(&reason); readErr != nil {
			return fmt.Errorf("authentication rejected")
		}
		return fmt.Errorf("authentication rejected: %s", reason)
	}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. If you maintain a fork: keep the shared secret at 16 bytes (AES-128) to match the server
  2. Report upstream if it fires on unmodified code, since it indicates memory/state corruption
  3. Diff local changes against upstream to find altered key-derivation logic
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := conn.Read(buf); err != nil && strings.Contains(err.Error(), "new crypto reader") {
    // defensive branch: indicates modified build or corruption; do not retry
    log.Error("unexpected crypto init failure", "err", err)
    return err
}

Prevention

When it happens

Trigger: Only reachable if newCryptoReader's internal aes.NewCipher(sharedSecret) fails, which requires a key size outside {16,24,32}; the fixed 16-byte allocation makes this unreachable under current code.

Common situations: None in normal operation. Seeing it usually means a fork modified the shared-secret size or the crypto constructor signature.

Related errors


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