fatedier/frp · critical

generate crypto random: %w

Error message

generate crypto random: %w

What it means

Thrown by newCryptoRandom when crypto/rand.Read fails while generating the 32-byte ClientRandom or ServerRandom. This is an OS-level entropy source failure; the code refuses to continue rather than use a weak random. Almost always an environment problem, not a logic bug.

Source

Thrown at pkg/proto/wire/crypto.go:189

}

func SelectAEADAlgorithm(clientAlgorithms []string) (string, bool) {
	for _, algorithm := range clientAlgorithms {
		if IsSupportedAEADAlgorithm(algorithm) {
			return algorithm, true
		}
	}
	return "", false
}

func IsSupportedAEADAlgorithm(algorithm string) bool {
	return Supports(supportedAEADAlgorithms, algorithm)
}

func newCryptoRandom() ([]byte, error) {
	b := make([]byte, CryptoRandomSize)
	if _, err := rand.Read(b); err != nil {
		return nil, fmt.Errorf("generate crypto random: %w", err)
	}
	return b, nil
}

func hasFastAESGCM() bool {
	switch runtime.GOARCH {
	case "amd64":
		return cpu.X86.HasAES &&
			cpu.X86.HasPCLMULQDQ &&
			cpu.X86.HasSSE41 &&
			cpu.X86.HasSSSE3
	case "arm64":
		return cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
	case "s390x":
		return cpu.S390X.HasAES &&
			cpu.S390X.HasAESCTR &&
			cpu.S390X.HasGHASH
	case "ppc64", "ppc64le":

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Check the host/kernel: on Linux ensure the kernel is >= 3.17 so getrandom() is available and never blocks after init.
  2. Loosen overly strict seccomp/gVisor profiles that deny getrandom syscalls to the frp process.
  3. As a last resort in early-boot scenarios, delay service start until the entropy pool is initialized (e.g. after random: crng init done in dmesg).
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := newCryptoRandom(); err != nil {
    // OS entropy failure: abort startup with a clear message; do not fall back to math/rand
    log.Fatalf("crypto/rand unavailable, cannot secure handshake: %v", err)
}

Prevention

When it happens

Trigger: crypto/rand.Read returns an error — extremely rare on Linux (getrandom(2) failure), more plausible on constrained containers, broken /dev/urandom setups, or exotic platforms during early boot before the CRNG is initialized.

Common situations: Minimal container images or VMs booted with low entropy; sandboxes/seccomp profiles that block getrandom; embedded targets where the kernel entropy pool initializes late.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/fa8fd50b40448219. Report an issue: GitHub.