crowdsecurity/crowdsec · critical
generate random master secret: %w
Error message
generate random master secret: %w
What it means
generateRandomSecret wraps a failure from crypto/rand.Read when generating the default 32-byte master secret (used when no master_secret is configured). crypto/rand essentially never fails on normal systems; failure indicates the OS entropy source is unavailable, so no secure key can be produced and startup must abort.
Source
Thrown at pkg/appsec/challenge/secret.go:28
"encoding/hex"
"errors"
"fmt"
)
// minSecretBytes is the smallest accepted master-secret length. 32 bytes is
// the natural minimum for an HMAC-SHA256 key with full security margin; we
// reject anything shorter as a configuration error rather than silently
// padding it.
const minSecretBytes = 32
// generateRandomSecret returns a fresh 32-byte secret suitable for use when
// no master_secret is configured. Single-instance deployments are fine with
// this; distributed deployments MUST configure a shared secret because each
// instance generates an independent random one here.
func generateRandomSecret() ([]byte, error) {
buf := make([]byte, 32)
if _, err := crand.Read(buf); err != nil {
return nil, fmt.Errorf("generate random master secret: %w", err)
}
return buf, nil
}
// ParseConfiguredSecret accepts a configured master secret as either a hex
// string (preferred — encodes raw bytes unambiguously) or a raw passphrase
// (fallback for human-edited configs). The result is at least minSecretBytes.
func ParseConfiguredSecret(value string) ([]byte, error) {
if value == "" {
return nil, errors.New("empty master secret")
}
// Hex form: even length, hex digits only.
if isHex(value) {
raw, err := hex.DecodeString(value)
if err == nil {
if len(raw) < minSecretBytes {
return nil, fmt.Errorf("hex master secret decodes to %d bytes; minimum is %d", len(raw), minSecretBytes)View on GitHub (pinned to 909b515798)
Solutions
- Fix the host entropy source: ensure /dev/urandom exists and getrandom(2) is not blocked by seccomp/AppArmor
- Configure an explicit master_secret so the random generator path is not used at all
- Check container runtime settings — run with a normal /dev mount rather than a stripped one
- Retry startup; if the failure is transient (early-boot entropy), it may succeed once the system is up
Example fix
// before: no secret configured, relying on random generation
opts := challenge.BuildOptions(cfg)
// after: explicit secret avoids the failing path
secret, _ := challenge.ParseConfiguredSecret("<64-hex-chars>")
opts := challenge.BuildOptions(cfg, challenge.WithMasterSecret(secret)) Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check is not practical; ensure host entropy availability and/or configure a secret
if os.Getenv("CS_CHALLENGE_MASTER_SECRET") == "" { log.Warn("no master_secret configured; using random (single-instance only)") } Try / catch
secret, err := challenge.ParseConfiguredSecret(cfgValue)
if err != nil {
secret, err = generateSecret() // surfaces the wrapped crypto/rand failure
if err != nil { return fmt.Errorf("challenge runtime init: %w", err) }
} Prevention
- Configure an explicit master_secret in production, especially distributed deployments
- Verify containers allow getrandom(2) and expose /dev/urandom
- Test startup in the same sandbox profile used in production
- Fail fast with a clear log line when random generation fails
When it happens
Trigger: NewChallengeRuntime is built without a configured master_secret and crypto/rand.Read fails — e.g. a container/sandbox where /dev/urandom or getrandom(2) is unavailable or blocked.
Common situations: Restricted containers or seccomp profiles blocking getrandom; embedded/minimal systems lacking an entropy device; heavily sandboxed CI environments.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- unable to generate a new random seed for JWT generation
- not enough entropy at random seed generation for JWT generat
- failed to generate nonce: %w
- generate challenge nonce: %w
- generate PoW prefix: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/6308f21c01854ade.
Report an issue: GitHub.