router-for-me/CLIProxyAPI · error
failed to generate random bytes: %w
Error message
failed to generate random bytes: %w
What it means
crypto/rand's rand.Read returned an error while filling the 96-byte buffer for the PKCE code verifier. On Go's standard library, rand.Read fails only when the OS entropy source is unavailable (getrandom(2)/dev/urandom errors). On any normal system this cannot happen; seeing it means the host or container runtime is broken at the OS level, or code replaced rand.Reader.
Source
Thrown at internal/auth/codex/pkce.go:42
// Generate code challenge using S256 method
codeChallenge := generateCodeChallenge(codeVerifier)
return &PKCECodes{
CodeVerifier: codeVerifier,
CodeChallenge: codeChallenge,
}, nil
}
// generateCodeVerifier creates a cryptographically secure random string to be used
// as the code verifier in the PKCE flow. The verifier is a high-entropy string
// that is later used to prove possession of the client that initiated the
// authorization request.
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 code challenge from a given code verifier.
// The challenge is derived by taking the SHA256 hash of the verifier and then
// Base64 URL-encoding the result. This is sent in the initial authorization
// request and later verified against the verifier.
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
- Exec into the container and check readability: `head -c 16 /dev/urandom | xxd`.
- Loosen the seccomp/apparmor profile to allow getrandom(2) and /dev/urandom access.
- Rebuild the image with a proper /dev (tmpfs dev mode) — run docker with --device /dev/urandom or default dev setup.
- Audit for rand.Reader overrides in vendored/test code.
Example fix
# before: docker run --security-opt seccomp=strict.json ... # after: allow getrandom in the profile or use the default profile docker run --security-opt seccomp=default.json ...
Defensive patterns
Strategy: validation
Validate before calling
// Probe the entropy source before relying on PKCE
b := make([]byte, 16)
if _, err := rand.Read(b); err != nil {
return fmt.Errorf("system entropy source unavailable: %w", err)
} Try / catch
if _, err := rand.Read(buf); err != nil {
// OS-level failure: fix the runtime (seccomp, /dev, kernel); do not retry blindly
return fmt.Errorf("crypto/rand unavailable: %w", err)
} Prevention
- Test container images with a simple crypto/rand read at build time.
- Allow getrandom(2) in seccomp profiles; ensure /dev/urandom exists.
- Never override rand.Reader in production code paths.
When it happens
Trigger: Container/seccomp profile blocking getrandom or access to /dev/urandom; a chroot missing /dev/urandom; test code swapping crypto/rand.Reader; ancient kernels without usable entropy early in boot.
Common situations: Over-restrictive Docker seccomp/apparmor profiles; minimal VM images; unit tests that inject failing readers and accidentally leak into production code paths.
Related errors
- failed to generate code verifier: %w
- failed to generate random bytes: %w
- failed to generate code verifier: %w
- token exchange failed with status %d: %s
- private_key invalid rsa: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/c688e4991f2f7e6a.
Report an issue: GitHub.