{"record":{"id":"2a1bdaf4a5e1f6e7","repo":"ory/kratos","slug":"argon2-p-d-not-in-1-d","errorCode":null,"errorMessage":"argon2 p=%d not in [1, %d]","messagePattern":"argon2 p=(.+?) not in \\[1, (.+?)\\]","errorType":"validation","errorClass":"ErrHashParametersOutOfBounds","httpStatus":null,"severity":"error","filePath":"hash/hash_limits.go","lineNumber":113,"sourceCode":"\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\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)","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/hash/hash_limits.go#L95-L131","documentation":"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.","triggerScenarios":"decodeArgon2idHash parses an $argon2id$ hash whose p= parameter is 0 or >16, during import validation or password comparison.","commonSituations":"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.","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"],"exampleFix":"// before (p=64, rejected)\n$argon2id$v=19$m=131072,t=3,p=64$...\n// after (p=4, accepted)\n$argon2id$v=19$m=131072,t=3,p=4$...","handlingStrategy":"validation","validationCode":"func argon2ParallelismOK(p uint8) bool { return p >= 1 && p <= 16 }\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(\"argon2 p out of range: %w\", err)\n}","preventionTips":["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"],"tags":["hashing","argon2"],"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"}