{"record":{"id":"fa42215a7cd0472f","repo":"ory/hydra","slug":"errmismatchedhashandpassword","errorCode":"ErrMismatchedHashAndPassword","errorMessage":"passwords do not match","messagePattern":"passwords do not match","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"oryx/hasherx/hasher_argon2.go","lineNumber":26,"sourceCode":"\t\"fmt\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/ory/x/otelx\"\n\n\t\"github.com/inhies/go-bytesize\"\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\n\t\"github.com/pkg/errors\"\n\t\"golang.org/x/crypto/argon2\"\n)\n\nvar (\n\tErrInvalidHash               = errors.New(\"the encoded hash is not in the correct format\")\n\tErrIncompatibleVersion       = errors.New(\"incompatible version of argon2\")\n\tErrMismatchedHashAndPassword = errors.New(\"passwords do not match\")\n)\n\ntype (\n\t// Argon2Config is the configuration for a Argon2 hasher.\n\tArgon2Config struct {\n\t\t// Memory is the amount of memory to use.\n\t\tMemory bytesize.ByteSize `json:\"memory\"`\n\n\t\t// Iterations is the number of iterations to use.\n\t\tIterations uint32 `json:\"iterations\"`\n\n\t\t// Parallelism is the number of threads to use.\n\t\tParallelism uint8 `json:\"parallelism\"`\n\n\t\t// SaltLength is the length of the salt to use.\n\t\tSaltLength uint32 `json:\"salt_length\"`\n\n\t\t// KeyLength is the length of the key to use.","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/hasherx/hasher_argon2.go#L8-L44","documentation":"ErrMismatchedHashAndPassword is the standard 'wrong password' result: the derived hash from the supplied password does not equal the stored hash. CompareArgon2id, CompareArgon2i and ComparePbkdf2 return it after a successful parse and constant-time comparison that failed.","triggerScenarios":"Calling Compare/CompareArgon2id/CompareArgon2i/ComparePbkdf2 with a password whose recomputed hash differs from the stored hash (comparator code paths at hash_comparator.go:71/96).","commonSituations":"End users typing wrong passwords; passwords changed server-side (password reset) while old sessions retry old credentials; hashes and salts copied between accounts during data migrations; case/whitespace differences from trimming inconsistencies at registration vs login.","solutions":["Return a generic invalid-credentials response to the client (do not leak which factor failed).","Verify the submitted password is preprocessed identically to registration (same trimming, casing, normalization/encoding).","Check the hash belongs to the account being authenticated (no cross-user hash mixups in migrations).","If the user forgot the password, trigger the password-reset flow rather than retrying."],"exampleFix":"// before\nif err := hasherx.Compare(ctx, []byte(pw), user.Hash); err != nil {\n  return err // leaks mismatch to caller\n}\n// after\nif err := hasherx.Compare(ctx, []byte(pw), user.Hash); err != nil {\n  if errors.Is(err, hasherx.ErrMismatchedHashAndPassword) {\n    return ErrInvalidCredentials // generic 401\n  }\n  return err\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isMismatch(err error) bool { return errors.Is(err, hasherx.ErrMismatchedHashAndPassword) }","tryCatchPattern":"if err := hasherx.Compare(ctx, []byte(pw), user.Hash); err != nil {\n  if errors.Is(err, hasherx.ErrMismatchedHashAndPassword) {\n    return http401InvalidCredentials() // generic, no user enumeration\n  }\n  return err // parse/algorithm problems surface separately\n}","preventionTips":["Normalize password input identically at registration and login (trim, encoding)","Apply rate limiting/lockout on repeated mismatches","After password resets, invalidate sessions holding old credentials","Check migrations do not mix hashes across accounts"],"tags":["passwords","hashing","authentication","crypto"],"backgroundTag":"password-hash-mismatch","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}