ory/kratos · error · ErrHashParametersOutOfBounds
argon2 p= not in [1, ]
Error message
argon2 p=%d not in [1, %d]
What it means
This error means an Argon2 hash declares a parallelism (p/lanes) parameter that is 0 or greater than 16. p=0 is invalid; the 16 ceiling covers up to 8-core hosts (default is 2*NumCPU) and bounds memory*lanes allocation per comparison. It wraps ErrHashParametersOutOfBounds from validateArgon2Params.
Solutions
- Check the p= field; it must be in [1, 16]
- Regenerate the hash with p matched to the target host (e.g. p=4)
- If hashes came from a high-core-count system, use rehash-on-login to bring parameters down gradually
Example fix
// before (p=64, rejected) $argon2id$v=19$m=131072,t=3,p=64$... // after (p=4, accepted) $argon2id$v=19$m=131072,t=3,p=4$...
Defensive patterns
Strategy: validation
Validate before calling
func argon2ParallelismOK(p uint8) bool { return p >= 1 && p <= 16 }
// Or pre-validate the whole hash: hash.ValidateImportedHash(hashed) Try / catch
if err := hash.ValidateImportedHash(raw); errors.Is(err, hash.ErrHashParametersOutOfBounds) {
return fmt.Errorf("argon2 p out of range: %w", err)
} Prevention
- Generate hashes with p sized for the smallest host that must compare them (e.g. p=4)
- Remember the ceiling is 16 (covers 8-core hosts at 2*NumCPU)
- Validate hashes at import time, not at first login
When it happens
Trigger: decodeArgon2idHash parses an $argon2id$ hash whose p= parameter is 0 or >16, during import validation or password comparison.
Common situations: Hashes generated on very large machines (e.g. p=64 on a 32-core server) being imported to smaller deployments; forged imports; corrupted hash strings.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- argon2 m= KiB not in [1, ]
- argon2 t= not in [1, ]
- firescrypt ln= exceeds max
- firescrypt r= not in [1, ]
- firescrypt p= not in [1, ]
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/2a1bdaf4a5e1f6e7.
Report an issue: GitHub.
Appendix: source
Thrown at hash/hash_limits.go:113
}
if r == 0 || r > maxScryptR {
return errors.Wrapf(ErrHashParametersOutOfBounds, "scrypt r=%d not in [1, %d]", r, maxScryptR)
}
if p == 0 || p > maxScryptP {
return errors.Wrapf(ErrHashParametersOutOfBounds, "scrypt p=%d not in [1, %d]", p, maxScryptP)
}
return nil
}
func validateArgon2Params(memoryKiB uint64, iterations uint32, parallelism uint8) error {
if memoryKiB == 0 || memoryKiB > uint64(maxArgon2MemoryKiB) {
return errors.Wrapf(ErrHashParametersOutOfBounds, "argon2 m=%d KiB not in [1, %d]", memoryKiB, maxArgon2MemoryKiB)
}
if iterations == 0 || iterations > maxArgon2Iterations {
return errors.Wrapf(ErrHashParametersOutOfBounds, "argon2 t=%d not in [1, %d]", iterations, maxArgon2Iterations)
}
if parallelism == 0 || parallelism > maxArgon2Parallelism {
return errors.Wrapf(ErrHashParametersOutOfBounds, "argon2 p=%d not in [1, %d]", parallelism, maxArgon2Parallelism)
}
return nil
}
func validatePbkdf2Params(iterations uint32) error {
if iterations == 0 || iterations > maxPbkdf2Iterations {
return errors.Wrapf(ErrHashParametersOutOfBounds, "pbkdf2 i=%d not in [1, %d]", iterations, maxPbkdf2Iterations)
}
return nil
}
func validateBcryptHashCost(hashed []byte) error {
cost, err := bcrypt.Cost(hashed)
if err != nil {
return err
}
if cost > maxBcryptCost {
return errors.Wrapf(ErrHashParametersOutOfBounds, "bcrypt cost=%d exceeds max %d", cost, maxBcryptCost)View on GitHub (pinned to b86338da04)