XTLS/Xray-core · error

generate shared secret: %w

Error message

generate shared secret: %w

What it means

crypto/rand.Read failed while filling the 16-byte AES shared secret used for the symmetric stream after the RSA exchange. This is an entropy-source failure from the OS CSPRNG, not a protocol error. On Linux crypto/rand essentially never fails unless getrandom(2) is unavailable (very old kernels, broken seccomp filters, or exhausted fd-restricted entropy setups in exotic sandboxes).

Source

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

	}

	if !bytes.Equal(publicKey, c.rsaPublicKey) {
		return fmt.Errorf("server public key mismatch")
	}

	k, err := x509.ParsePKIXPublicKey(publicKey)
	if err != nil {
		return fmt.Errorf("parse server public key: %w", err)
	}

	rsaPublicKey, ok := k.(*rsa.PublicKey)
	if !ok {
		return fmt.Errorf("parse server public key: not rsa")
	}

	sharedSecret := make([]byte, 16)
	if _, err = rand.Read(sharedSecret); err != nil {
		return fmt.Errorf("generate shared secret: %w", err)
	}

	encryptedSharedSecret, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, sharedSecret)
	if err != nil {
		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,

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Verify /dev/urandom exists and is readable inside the environment (ls -l /dev/urandom && head -c 16 /dev/urandom >/dev/null)
  2. Relax the seccomp/container profile to allow the getrandom syscall (Docker default profiles already do)
  3. Move the workload to a standard kernel >= 3.17
  4. If running under a WASM/embedded target, provide a platform CSPRNG or run the tunnel on the host side
Defensive patterns

Strategy: validation

Validate before calling

if _, err := rand.Read(make([]byte, 16)); err != nil {
    return fmt.Errorf("environment CSPRNG unavailable: %w", err)
}

Try / catch

n, err := conn.Read(buf)
if err != nil && strings.Contains(err.Error(), "generate shared secret") {
    // entropy source failure: fix the runtime environment, do not retry in-process
    log.Fatal("CSPRNG unavailable; check /dev/urandom and seccomp profile")
}

Prevention

When it happens

Trigger: First Read/Write on a WrapConnClient connection triggers handshake(), which calls rand.Read(sharedSecret); the call returns an error, e.g. under a container/seccomp profile that blocks getrandom, or on a kernel older than 3.17 without /dev/urandom available.

Common situations: Overly restrictive Docker/gVisor/seccomp sandboxes; chroot environments without /dev/urandom mounted; some minimal VMs or WASM targets. Extremely rare on normal hosts.

Related errors


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