Skip to content

How to Force a User to Change Password at Next Login on Linux and RHEL (passwd and chage)

Updated 4 min read

Updated: 9 October 2026 · Applies to: AlmaLinux 9.8 and 10.2 (RHEL 9 and 10 family), Ubuntu 24.04 and 26.04, Debian 13 (passwd and chage from shadow-utils 4.9 to 4.17)

To make a user choose a new password the next time they log in, expire their current password as root:

sudo passwd --expire vyga      # short form: passwd -e vyga
sudo chage -l vyga             # check: "password must be changed"

sudo chage -d 0 vyga does exactly the same. The user can still log in with the old password once, but must set a new one before they get a shell. Both commands work the same on AlmaLinux, Rocky Linux, RHEL, Ubuntu and Debian.

Change a password: the passwd command

If you only want to change a password, these are the commands (the full guide is how to change a user password in Linux):

passwd                         # change your own password (asks for the current one)
sudo passwd vyga               # root or sudo: set another user's password
echo 'vyga:N3w-Strong-Pass' | sudo chpasswd   # in a bash script, no prompts
  • Ubuntu, Debian and AlmaLinux 10 answer passwd: password updated successfully.
  • AlmaLinux 9 (and RHEL 9 or Rocky Linux 9) answers Changing password for user vyga. and passwd: all authentication tokens updated successfully.
  • In RHEL 10 the separate passwd package is gone: according to Red Hat it was replaced by shadow-utils, which is why the messages changed. The commands are the same.
  • For scripts, chpasswd works everywhere. echo 'Pass' | sudo passwd --stdin vyga worked on AlmaLinux 9 and 10, Debian 13 and Ubuntu 26.04, but Ubuntu 24.04 replied passwd: unrecognized option '--stdin'.

Method 1: expire the password with passwd

  1. Expire it:
    $ sudo passwd --expire vyga
    passwd: password changed.
    On AlmaLinux 9 the reply is Expiring password for user vyga. and passwd: Success. Despite the wording, the password itself is not changed; only its "last changed" date is reset.
  2. Check the result:
    $ sudo chage -l vyga
    Last password change                                : password must be changed
    Password expires                                    : password must be changed
    Password inactive                                   : password must be changed
    Account expires                                     : never
    sudo passwd -S vyga now shows the date 1970-01-01, and the third field of the user's line in /etc/shadow is 0.

Method 2: set the last change date to 0 with chage

sudo chage -d 0 vyga
# the same:
sudo chage --lastday 0 vyga
sudo chage --lastday 1970-01-01 vyga

-d sets the day the password was last changed, counted from 1 January 1970. Day 0 means "never changed", so the system treats it as expired. In our tests the chage -l output was identical to method 1.

What the user sees at the next login

Logging in with su on AlmaLinux 10 (Ubuntu and Debian add the line Changing password for vyga.):

$ su - vyga
Password:
You are required to change your password immediately (administrator enforced).
Current password:
New password:
Retype new password:

After the change, chage -l shows today's date again. Even root running su - vyga got the same prompt.

Over SSH, the server checks the expiry after the user has logged in, also with an SSH key. In an interactive session, according to the OpenSSH source code, the server prints WARNING: Your password has expired., runs passwd and then closes the connection, so the user logs in again with the new password. Without a terminal (a remote command, scp, sftp or an automation tool) the login simply fails:

$ ssh vyga@server id
You are required to change your password immediately (administrator enforced).
WARNING: Your password has expired.
Password change required but no TTY available.

So do not expire the password of an account that backups, deployments or monitoring use over SSH: they stop working until someone logs in and sets a new password.

Give a new user a temporary password

sudo useradd -m vyga
echo 'vyga:Temp-Pass-55w' | sudo chpasswd
sudo chage -d 0 vyga

Send the temporary password by a separate channel. At the first login the user has to replace it.

Force a change for every normal user

for u in $(awk -F: '$3>=1000 && $3<65000 {print $1}' /etc/passwd); do
  sudo chage -d 0 "$u"
done

Normal users start at UID 1000 on all the distributions above; the loop skips root and system accounts. Check the list first with the awk part alone and remove service accounts from it.

Undo it

sudo chage -d $(date +%F) vyga

This sets the last change to today, so the old password works normally again.

Expire passwords regularly

To make users change their password every 90 days instead of once, set a maximum age with sudo chage -M 90 vyga, and a warning period with -W. See how to manage user password expiration and aging and how to prevent users from reusing old passwords. If passwd fails with "Authentication token manipulation error", see this fix.

Official documentation: passwd(1) and chage(1) manual pages.

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Linux server management

hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.

Was this answer helpful?

Still stuck? Open a ticket