{"record":{"id":"d2c62f13c9a37bbb","repo":"ory/kratos","slug":"pbkdf2-i-d-not-in-1-d","errorCode":null,"errorMessage":"pbkdf2 i=%d not in [1, %d]","messagePattern":"pbkdf2 i=(.+?) not in \\[1, (.+?)\\]","errorType":"validation","errorClass":"ErrHashParametersOutOfBounds","httpStatus":null,"severity":"error","filePath":"hash/hash_limits.go","lineNumber":120,"sourceCode":"\treturn nil\n}\n\nfunc validateArgon2Params(memoryKiB uint64, iterations uint32, parallelism uint8) error {\n\tif memoryKiB == 0 || memoryKiB > uint64(maxArgon2MemoryKiB) {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"argon2 m=%d KiB not in [1, %d]\", memoryKiB, maxArgon2MemoryKiB)\n\t}\n\tif iterations == 0 || iterations > maxArgon2Iterations {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"argon2 t=%d not in [1, %d]\", iterations, maxArgon2Iterations)\n\t}\n\tif parallelism == 0 || parallelism > maxArgon2Parallelism {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"argon2 p=%d not in [1, %d]\", parallelism, maxArgon2Parallelism)\n\t}\n\treturn nil\n}\n\nfunc validatePbkdf2Params(iterations uint32) error {\n\tif iterations == 0 || iterations > maxPbkdf2Iterations {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"pbkdf2 i=%d not in [1, %d]\", iterations, maxPbkdf2Iterations)\n\t}\n\treturn nil\n}\n\nfunc validateBcryptHashCost(hashed []byte) error {\n\tcost, err := bcrypt.Cost(hashed)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif cost > maxBcryptCost {\n\t\treturn errors.Wrapf(ErrHashParametersOutOfBounds, \"bcrypt cost=%d exceeds max %d\", cost, maxBcryptCost)\n\t}\n\treturn nil\n}\n\n// ValidateImportedHash performs cost-parameter bounds checking on a hash\n// before it is persisted via the admin identity import API. It is the\n// import-time counterpart to the bounds checks in the compare* paths and","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/hash/hash_limits.go#L102-L138","documentation":"This error means a PBKDF2 hash declares an iteration count i that is 0 or greater than 10,000,000. i=0 does no key-stretching; a huge i makes every password comparison take unbounded CPU time, so the package caps it at ~10x OWASP's strongest published recommendation. It wraps ErrHashParametersOutOfBounds from validatePbkdf2Params during hash decode.","triggerScenarios":"decodePbkdf2Hash parses a PBKDF2 hash (e.g. $pbkdf2-sha256$i=... or {PBKDF2}... format) whose iteration count is 0 or exceeds 10,000,000, via ValidateImportedHash or during password comparison.","commonSituations":"Importing hashes from systems configured with tens of millions of iterations (e.g. long-lived high-security deployments or FIPS-style configs); hand-edited hash strings; zeroed iterations from a corrupt export.","solutions":["Check the iteration count in the hash string; it must be in [1, 10000000]","Re-hash with an OWASP 2023 recommendation (600k for SHA-256, 210k for SHA-512)","For legacy users with higher counts, migrate via rehash-on-login after successful authentication"],"exampleFix":"// before (i=50000000, rejected)\n$pbkdf2-sha256$i=50000000$...\n// after (i=600000, accepted)\n$pbkdf2-sha256$i=600000$...","handlingStrategy":"validation","validationCode":"func pbkdf2IterationsOK(i uint32) bool { return i >= 1 && i <= 10_000_000 }\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(\"pbkdf2 iterations out of range: %w\", err)\n}","preventionTips":["Follow OWASP 2023 guidance: 600k (SHA-256) / 210k (SHA-512) iterations","Audit legacy PBKDF2 exports for FIPS-style multi-million iteration counts before import","Use ValidateImportedHash at intake and rehash-on-login to lower iteration counts over time"],"tags":["hashing","pbkdf2"],"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"}