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

  1. Fix the configured PasswordStrength (App settings) to a value the hashing library accepts.
  2. Check the wrapped %s error for the concrete hashing failure and address it.
  3. Verify the password passes ValidateNewPassword first; ensure the request sends a valid Pass field.
  4. 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

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


AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05). Data as JSON: /api/errors/93b5b26a6a293db6. Report an issue: GitHub.