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

  1. Confirm host entropy is available: `cat /proc/sys/kernel/random/entropy_avail` and retry after boot settles.
  2. Move the workload to a standard kernel/runtime with working getrandom(2).
  3. 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

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


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/066acfa9a2ddc074. Report an issue: GitHub.