{"record":{"id":"c1eb5e05e337835e","repo":"ory/kratos","slug":"firescrypt-r-d-not-in-1-d","errorCode":null,"errorMessage":"firescrypt r=%d not in [1, %d]","messagePattern":"firescrypt r=(.+?) not in \\[1, (.+?)\\]","errorType":"validation","errorClass":"ErrHashParametersOutOfBounds","httpStatus":null,"severity":"error","filePath":"hash/hash_limits.go","lineNumber":84,"sourceCode":"\t// maxPbkdf2Iterations bounds PBKDF2 i. OWASP 2023 recommends 600k\n\t// (SHA-256) / 210k (SHA-512). 10M ≈ 10× the strongest published\n\t// recommendation and bounds CPU to a few seconds on modern hardware.\n\tmaxPbkdf2Iterations uint32 = 10_000_000\n\n\t// maxBcryptCost bounds bcrypt cost. The format spec allows 4–31, but\n\t// cost grows exponentially: cost 12 (Kratos, PHP, Django default) is\n\t// ~250 ms; cost 14 (high-security guidance) is ~1 s; cost 15 (practical\n\t// max for interactive use) is ~2 s; cost 17 is ~8 s. No mainstream\n\t// platform defaults above cost 12.\n\tmaxBcryptCost = 15\n)\n\nfunc validateFirebaseScryptParams(logN, r, p uint32) error {\n\tif logN > maxScryptLogN {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"firescrypt ln=%d exceeds max %d\", logN, maxScryptLogN)\n\t}\n\tif r == 0 || r > maxScryptR {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"firescrypt r=%d not in [1, %d]\", r, maxScryptR)\n\t}\n\tif p == 0 || p > maxScryptP {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"firescrypt p=%d not in [1, %d]\", p, maxScryptP)\n\t}\n\treturn nil\n}\n\nfunc validateScryptParams(n, r, p uint32) error {\n\tif n == 0 || n > maxScryptN {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"scrypt N=%d not in [1, %d]\", n, maxScryptN)\n\t}\n\tif r == 0 || r > maxScryptR {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"scrypt r=%d not in [1, %d]\", r, maxScryptR)\n\t}\n\tif p == 0 || p > maxScryptP {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"scrypt p=%d not in [1, %d]\", p, maxScryptP)\n\t}\n\treturn nil","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/hash/hash_limits.go#L66-L102","documentation":"This error means a Firebase scrypt hash declares an r (block size) parameter outside the valid range [1, 8]. r=0 is invalid because the scrypt memory cost 128*N*r would be zero; r>8 exceeds the RFC 7914 standard block size and would inflate memory use beyond the package's bounds. It wraps ErrHashParametersOutOfBounds from validateFirebaseScryptParams during hash decode.","triggerScenarios":"decodeFirebaseScryptHash encounters a $firescrypt hash string with r=0 or r>8 in its parameters, either via ValidateImportedHash on import or during password comparison.","commonSituations":"Malformed or hand-crafted hash strings with missing/zero parameters; hashes exported from tools using non-standard scrypt block sizes; typo when manually constructing a hash for seeding test users.","solutions":["Inspect the r field in the hash string and ensure it is an integer in [1, 8] (Firebase uses r=8)","Regenerate or re-export the hash with the standard r=8","If the hash is corrupted, re-hash the password from its source rather than repairing the string by hand"],"exampleFix":"// before (r=0, invalid)\n$firescrypt$ln=14$r=0$p=1$...\n// after (r=8, valid)\n$firescrypt$ln=14$r=8$p=1$...","handlingStrategy":"validation","validationCode":"func firebaseScryptROK(r uint32) bool { return r >= 1 && r <= 8 }\n// Or pre-validate the whole hash: hash.ValidateImportedHash(hashed)","typeGuard":null,"tryCatchPattern":"if err := hash.ValidateImportedHash(raw); errors.Is(err, hash.ErrHashParametersOutOfBounds) {\n    return fmt.Errorf(\"invalid firescrypt r: %w\", err)\n}","preventionTips":["Always export Firebase hashes with r=8 (Firebase's standard block size)","Never hand-construct hash strings for seeding; use the exporter tooling","Validate hashes at import time with ValidateImportedHash"],"tags":["hashing","scrypt","firebase"],"backgroundTag":"value-out-of-range","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}