gotify/server · error
failed to prepare password: %s
Error message
failed to prepare password: %s
What it means
In CreateUser, after validating the new password, the server hashes it with password.CreatePassword using the configured PasswordStrength. If hashing fails (e.g. invalid strength parameter or bcrypt/argon2 failure), the request is aborted with a 500 and "failed to prepare password: <err>". It indicates an internal password-hashing problem, not a bad password.
Source
Thrown at api/user.go:197
// $ref: "#/definitions/Error"
// 401:
// description: Unauthorized
// schema:
// $ref: "#/definitions/Error"
// 403:
// description: Forbidden
// schema:
// $ref: "#/definitions/Error"
func (a *UserAPI) CreateUser(ctx *gin.Context) {
user := model.CreateUserExternal{}
if err := ctx.Bind(&user); err == nil {
if err := password.ValidateNewPassword(user.Pass); err != nil {
ctx.AbortWithError(http.StatusBadRequest, err)
return
}
pw, err := password.CreatePassword(user.Pass, a.PasswordStrength)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to prepare password: %s", err))
return
}
internal := &model.User{
Name: user.Name,
Admin: user.Admin,
Pass: pw,
}
existingUser, err := a.DB.GetUserByName(internal.Name)
if success := successOrAbort(ctx, 500, err); !success {
return
}
var requestedBy *model.User
uid := auth.TryGetUserID(ctx)
if uid != nil {
requestedBy, err = a.DB.GetUserByID(*uid)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("could not get user: %s", err))View on GitHub (pinned to 14bfc25627)
Solutions
- Fix the configured PasswordStrength (App settings) to a value the hashing library accepts.
- Check the wrapped %s error for the concrete hashing failure and address it.
- Verify the password passes ValidateNewPassword first; ensure the request sends a valid Pass field.
- Upgrade/patch the password package if the hash function itself is failing.
Example fix
// before (config) PASSWORD_STRENGTH=99 // after PASSWORD_STRENGTH=11
Defensive patterns
Strategy: validation
Validate before calling
if err := password.ValidateNewPassword(pass); err != nil {
return fmt.Errorf("invalid password: %w", err)
} Try / catch
if resp.StatusCode == http.StatusInternalServerError && strings.Contains(body, "failed to prepare password") {
// server-side hashing config issue; report to admin, don't retry
} Prevention
- Keep PasswordStrength within the hasher's supported range.
- Always validate passwords client- and server-side before hashing.
- Validate hashing config at application startup.
When it happens
Trigger: POST to the user-creation endpoint with a password that passes ValidateNewPassword but fails password.CreatePassword — typically when a.PasswordStrength is misconfigured or out of the hashing library's accepted range.
Common situations: App.yaml/env sets an unsupported PasswordStrength value (e.g. cost outside bcrypt 4–31); embedding an alternative hasher that errors; resource exhaustion during key derivation.
Related errors
- issuer claim was empty
- subject claim was empty
- username claim was empty
- invalid credentials
- password must not be empty
AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05).
Data as JSON: /api/errors/93b5b26a6a293db6.
Report an issue: GitHub.