crowdsecurity/crowdsec · error
keyring master secret is %d bytes; minimum is %d
Error message
keyring master secret is %d bytes; minimum is %d
What it means
NewKeyRing rejects a master secret shorter than minSecretBytes. The master secret is the root key material from which per-key cookie secrets are derived; a short secret is brute-forceable, so the constructor fails fast. Callers should validate earlier via WithMasterSecret/ParseConfiguredSecret, but NewKeyRing enforces it defensively.
Source
Thrown at pkg/appsec/challenge/keyring.go:100
logger *log.Entry
mu sync.RWMutex
cache map[int64][]byte // epoch -> per-epoch sign key
}
// log returns the component logger (never nil; see the logger field).
func (k *KeyRing) log() *log.Entry {
return k.logger
}
// NewKeyRing constructs a KeyRing. masterSecret must be at least minSecretBytes
// long (callers should already have validated this via WithMasterSecret); the
// rotation interval must be at least keyringMinRotation. maxLive defaults to
// keyringDefaultMaxLive when zero.
func NewKeyRing(masterSecret []byte, rotationInterval time.Duration, maxLive int) (*KeyRing, error) {
if len(masterSecret) < minSecretBytes {
return nil, fmt.Errorf("keyring master secret is %d bytes; minimum is %d", len(masterSecret), minSecretBytes)
}
if rotationInterval < keyringMinRotation {
return nil, fmt.Errorf("keyring rotation interval %s is below the floor %s", rotationInterval, keyringMinRotation)
}
if maxLive <= 0 {
maxLive = keyringDefaultMaxLive
}
return &KeyRing{
masterSecret: masterSecret,
rotationInterval: rotationInterval,
maxLive: maxLive,
clockSkew: keyringClockSkew,
masterCookieKey: deriveMasterCookieKey(masterSecret),
logger: log.StandardLogger().WithField("module", "challenge"),
now: time.Now,
cache: make(map[int64][]byte),
}, nilView on GitHub (pinned to 909b515798)
Solutions
- Set a master_secret of at least minSecretBytes — prefer a 32-byte hex value (64 hex chars), e.g. `openssl rand -hex 32`
- If using a passphrase, ensure it is at least minSecretBytes bytes of actual text
- Run the value through challenge.ParseConfiguredSecret first to get a precise error before constructing the keyring
- On distributed deployments, ensure every instance uses the same sufficiently long shared secret
Example fix
// before
kr, err := challenge.NewKeyRing([]byte("short"), time.Hour, 0)
// after
secret, err := challenge.ParseConfiguredSecret(os.Getenv("CS_CHALLENGE_SECRET"))
if err != nil { return err }
kr, err := challenge.NewKeyRing(secret, time.Hour, 0) Defensive patterns
Strategy: validation
Validate before calling
if len(secret) < minSecretBytes { return fmt.Errorf("master secret must be at least %d bytes", minSecretBytes) }
kr, err := challenge.NewKeyRing(secret, rotation, maxLive) Prevention
- Generate secrets with `openssl rand -hex 32`
- Validate configuration with ParseConfiguredSecret before constructing a KeyRing
- Enforce secret length checks in config-loading tests
- Use the documented option helpers (WithMasterSecret) rather than calling NewKeyRing directly
When it happens
Trigger: Calling NewKeyRing directly (or BuildOptions wiring a configured secret into it) with a masterSecret slice under minSecretBytes — e.g. a hex secret that decodes to too few bytes, or a short passphrase passed raw.
Common situations: An operator configured a short master_secret (e.g. 'abc123') in the AppSec challenge config; a hex string was entered without realizing it must decode to the minimum byte length; tests constructing a KeyRing with a stub secret.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- build challenge keyring: %w
- keyring rotation interval %s is below the floor %s
- hex master secret decodes to %d bytes; minimum is %d
- passphrase master secret is %d bytes; minimum is %d
- missing lapi client credentials
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/026354273bf20fee.
Report an issue: GitHub.