router-for-me/CLIProxyAPI · critical
failed to generate random bytes: %w
Error message
failed to generate random bytes: %w
What it means
The root cause behind error 188: crypto/rand.Read failed while generating the 96-byte PKCE verifier. Go's crypto/rand only errors when the OS entropy source is genuinely unavailable; on healthy Linux/macOS/Windows systems this effectively never happens. Treat it as an environment problem, not a code problem.
Source
Thrown at internal/auth/claude/pkce.go:44
}
// Generate code challenge using S256 method
codeChallenge := generateCodeChallenge(codeVerifier)
return &PKCECodes{
CodeVerifier: codeVerifier,
CodeChallenge: codeChallenge,
}, nil
}
// generateCodeVerifier creates a cryptographically random string
// of 128 characters using URL-safe base64 encoding
func generateCodeVerifier() (string, error) {
// Generate 96 random bytes (will result in 128 base64 characters)
bytes := make([]byte, 96)
_, err := rand.Read(bytes)
if err != nil {
return "", fmt.Errorf("failed to generate random bytes: %w", err)
}
// Encode to URL-safe base64 without padding
return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(bytes), nil
}
// generateCodeChallenge creates a SHA256 hash of the code verifier
// and encodes it using URL-safe base64 encoding without padding
func generateCodeChallenge(codeVerifier string) string {
hash := sha256.Sum256([]byte(codeVerifier))
return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(hash[:])
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Confirm host entropy is available: `cat /proc/sys/kernel/random/entropy_avail` and retry after boot settles.
- Move the workload to a standard kernel/runtime with working getrandom(2).
- If a startup script triggers login immediately at boot, delay it until the system is seeded.
Defensive patterns
Strategy: retry
Validate before calling
b := make([]byte, 16)
if _, err := rand.Read(b); err != nil {
return errors.New("entropy source unavailable; boot the host fully before OAuth flows")
} Try / catch
if _, err := rand.Read(buf); err != nil {
time.Sleep(2 * time.Second) // early-boot CRNG can block briefly
if _, err = rand.Read(buf); err != nil {
return fmt.Errorf("CSPRGM unavailable: %w", err)
}
} Prevention
- On fresh VMs/containers, wait for /proc/sys/kernel/random/entropy_avail to report seeded state before automating login.
- Keep PKCE generation on crypto/rand only; do not swap in math/rand.
When it happens
Trigger: rand.Read(bytes) returning an error inside generateCodeVerifier during any Claude OAuth login attempt; observed on early-boot systems where getrandom(2) blocks, or in sandboxed runtimes that do not implement the entropy syscalls.
Common situations: Containers started within seconds of host boot; embedded/minimal VMs; CI runners on exotic hypervisors with poor entropy passthrough; never on typical dev machines.
Related errors
- failed to generate code verifier: %w
- failed to generate random bytes: %w
- failed to generate code verifier: %w
- failed to open uploaded file: %w
- fetch Claude OAuth %s: HTTP client is nil
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/066acfa9a2ddc074.
Report an issue: GitHub.