{"record":{"id":"a8e005475e8a68b8","repo":"crowdsecurity/crowdsec","slug":"passphrase-master-secret-is-d-bytes-minimum-is","errorCode":null,"errorMessage":"passphrase master secret is %d bytes; minimum is %d","messagePattern":"passphrase master secret is (.+?) bytes; minimum is (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/secret.go","lineNumber":54,"sourceCode":"func ParseConfiguredSecret(value string) ([]byte, error) {\n\tif value == \"\" {\n\t\treturn nil, errors.New(\"empty master secret\")\n\t}\n\n\t// Hex form: even length, hex digits only.\n\tif isHex(value) {\n\t\traw, err := hex.DecodeString(value)\n\t\tif err == nil {\n\t\t\tif len(raw) < minSecretBytes {\n\t\t\t\treturn nil, fmt.Errorf(\"hex master secret decodes to %d bytes; minimum is %d\", len(raw), minSecretBytes)\n\t\t\t}\n\t\t\treturn raw, nil\n\t\t}\n\t\t// Fall through to passphrase handling on hex parse failure — defensive.\n\t}\n\n\tif len(value) < minSecretBytes {\n\t\treturn nil, fmt.Errorf(\"passphrase master secret is %d bytes; minimum is %d\", len(value), minSecretBytes)\n\t}\n\n\treturn []byte(value), nil\n}\n\nfunc isHex(s string) bool {\n\tif s == \"\" || len(s)%2 != 0 {\n\t\treturn false\n\t}\n\tfor i := range len(s) {\n\t\tc := s[i]\n\t\tswitch {\n\t\tcase c >= '0' && c <= '9':\n\t\tcase c >= 'a' && c <= 'f':\n\t\tcase c >= 'A' && c <= 'F':\n\t\tdefault:\n\t\t\treturn false\n\t\t}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/secret.go#L36-L72","documentation":"ParseConfiguredSecret treats a non-hex master_secret as a passphrase and rejects it when its byte length is under minSecretBytes. The passphrase is used directly as key material, so it must be long enough to resist brute force.","triggerScenarios":"BuildOptions parses a master_secret that is not valid hex and whose raw string length is below minSecretBytes — e.g. `master_secret: \"hunter2\"`.","commonSituations":"Operators picking a short memorable passphrase; YAML-truncated or quoted strings losing characters; secrets from templating that expanded to shorter values; test cases like TestParseConfiguredSecret_PassphraseTooShort.","solutions":["Use a passphrase of at least minSecretBytes bytes (e.g. a long diceware phrase or `openssl rand -base64 32`)","Prefer the hex form: `openssl rand -hex 32`","Verify the deployed config value actually reaches the process intact (quotes, whitespace, env interpolation)","Ensure all distributed instances share the corrected full-length secret"],"exampleFix":"# before\nmaster_secret: \"changeme\"\n# after\nmaster_secret: \"correct horse battery staple gravy ledger nine violet\"","handlingStrategy":"validation","validationCode":"if !isHex(cfg.MasterSecret) && len(cfg.MasterSecret) < 32 {\n    return fmt.Errorf(\"master_secret passphrase must be at least 32 bytes\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer generated hex secrets over human passphrases","Validate the secret with ParseConfiguredSecret during deployment, not at runtime failure","Check YAML quoting/interpolation so the full value reaches the process","Share the same validated secret across all instances"],"tags":["crypto","passphrase","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}