gotify/server · error
password must not be empty
Error message
password must not be empty
What it means
Validation error from password.ValidateNewPassword in auth/password/password.go: an empty password string was supplied where a new password is required. The function is called by CreateUser, ChangePassword, and the user-update handler before hashing, so user creation or password change is rejected with HTTP 400.
Source
Thrown at auth/password/password.go:11
package password
import (
"errors"
"golang.org/x/crypto/bcrypt"
)
func ValidateNewPassword(pw string) error {
if pw == "" {
return errors.New("password must not be empty")
}
if len([]byte(pw)) > 72 {
return bcrypt.ErrPasswordTooLong
}
return nil
}
// CreatePassword returns a hashed version of the given password.
func CreatePassword(pw string, strength int) ([]byte, error) {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(pw), strength)
return hashedPassword, err
}
// ComparePassword compares a hashed password with its possible plaintext equivalent.
func ComparePassword(hashedPassword, password []byte) bool {
return bcrypt.CompareHashAndPassword(hashedPassword, password) == nil
}
View on GitHub (pinned to 14bfc25627)
Solutions
- Omit the pass/pass field entirely when you don't want to change the password (empty string in update means 'no change' only if the handler checks; for create a real password is required)
- Send a non-empty password when creating a user or changing a password
- Also keep the password <= 72 bytes since the same validator enforces bcrypt's length limit
Example fix
// before
await api.updateUser(id, { name: 'bob', pass: '' });
// after: only send pass when actually changing it
const payload = { name: 'bob' };
if (newPassword) payload.pass = newPassword;
await api.updateUser(id, payload); Defensive patterns
Strategy: validation
Validate before calling
function validateNewPassword(pw) {
if (typeof pw !== 'string' || pw.length === 0) throw new Error('password must not be empty');
if (Buffer.byteLength(pw, 'utf8') > 72) throw new Error('password longer than 72 bytes');
return pw;
}
validateNewPassword(newPassword); Type guard
function isValidPassword(pw) {
return typeof pw === 'string' && pw.length > 0 && Buffer.byteLength(pw, 'utf8') <= 72;
} Try / catch
try {
await api.createUser({ name, pass: pw });
} catch (e) {
if (e.status === 400 && /password/.test(e.message)) {
throw new ValidationError('password rejected by server: ' + e.message);
}
throw e;
} Prevention
- Validate password non-empty (and <=72 bytes) client-side before sending
- When updating users, omit the pass field rather than sending an empty string
- Enforce minimum-length rules in your UI to catch empties before submission
- Remember the limit is bytes, not characters, for multibyte passwords
When it happens
Trigger: POST /users (admin create user) or password-change endpoint with pass == "" or the pass field omitted; user-update (PUT) setting a password to an empty string instead of leaving it out.
Common situations: Client sends JSON without the pass field and the server treats empty string as 'set password'; forms with an optional password field submit empty values; API clients defaulting missing fields to empty strings in serialization.
Related errors
- file must be an image
- invalid file extension
- appid is required when not authenticating with an applicatio
- appid not found
- cannot delete internal application
AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05).
Data as JSON: /api/errors/574e972ad3a694a6.
Report an issue: GitHub.