chage Command in Linux: Syntax, Options & Password Aging Examples

Deepak Prasad
Tested on Ubuntu 25.04 (Plucky Puffin)
Package shadow
shadow-utils
Applies to Ubuntu, Debian, RHEL, Fedora, SUSE
Privilege sudo or root
Man page chage(1)
Scope chage views and edits password aging fields in /etc/shadow — maximum password age, warning days, inactivity lock, and account expiry. Use it to enforce rotation policy or set temporary accounts without editing shadow by.
Related guides Linux commands

Short on time?Beta Get the gist of this 8-minute read in seconds, then ask follow-up questions

chage — quick reference

View aging

When to use Command
Show all password and account aging fields sudo chage -l username
List dates in ISO8601 (YYYY-MM-DD) format sudo chage -i -l username

Password timing

When to use Command
Set maximum password age in days (-1 = never) sudo chage -M DAYS username
Set minimum days between password changes sudo chage -m DAYS username
Days before expiry to warn the user sudo chage -W DAYS username
Set last password change date sudo chage -d YYYY-MM-DD username
Force password change at next login sudo chage -d 0 username
Remove maximum age (password never expires) sudo chage -M -1 username

Account lock and expiry

When to use Command
Lock account N days after password expires (inactivity) sudo chage -I DAYS username
Disable inactivity lock sudo chage -I -1 username
Set calendar account expiry date sudo chage -E YYYY-MM-DD username
Remove account expiry sudo chage -E -1 username
Disable account immediately (-E 0) sudo chage -E 0 username

Interactive and chroot

When to use Command
Prompt for each aging field interactively sudo chage username
Operate on accounts under a chroot sudo chage -R /mnt/sysroot -l username
Prefix path for etc/shadow location sudo chage -P /mnt/etc -l username

Help

When to use Command
Show built-in usage chage -h
chage --help

chage — command syntax

Synopsis from chage --help on Ubuntu 25.04 (chage from passwd 1:4.16.0-7ubuntu1):

text
Usage: chage [options] LOGIN

Options:
  -d, --lastday LAST_DAY        set date of last password change to LAST_DAY
  -E, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE
  -i, --iso8601                 use YYYY-MM-DD when printing dates
  -I, --inactive INACTIVE       set password inactive after expiration to INACTIVE
  -l, --list                    show account aging information
  -m, --mindays MIN_DAYS        set minimum number of days before password change to MIN_DAYS
  -M, --maxdays MAX_DAYS        set maximum number of days before password change to MAX_DAYS
  -R, --root CHROOT_DIR         directory to chroot into
  -P, --prefix PREFIX_DIR       directory prefix
  -W, --warndays WARN_DAYS      set expiration warning days to WARN_DAYS

chage edits aging columns in /etc/shadow (fields 3–8). It does not change the password hash — use passwd for that.


chage — command examples

Essential List current aging with chage -l

Start here before changing policy — you see last change, expiry, inactivity, and account expiration in one place.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -l cschage_demo

Sample output:

output
Last password change					: Jul 01, 2026
Password expires					: never
Password inactive					: never
Account expires						: never
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7

Clean up at the end of your test:

bash
sudo userdel -r cschage_demo
Essential Set max age, min age, warning, and inactivity

Typical corporate rotation: 90-day passwords, 7-day minimum between changes, warn 7 days early, lock 10 days after expiry if not changed.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -M 90 cschage_demo
sudo chage -m 7 cschage_demo
sudo chage -W 7 cschage_demo
sudo chage -I 10 cschage_demo
sudo chage -l cschage_demo

Sample output (dates shift with your test day):

text
Maximum number of days between password change		: 90
Minimum number of days between password change		: 7
Number of days of warning before password expires	: 7
Password inactive					: 10
bash
sudo userdel -r cschage_demo
Essential Force password change at next login (-d 0)

Sets last-change to the epoch — the password is treated as expired immediately. The account is not locked; login continues after a new password is set.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -d 0 cschage_demo
sudo chage -l cschage_demo | head -5

Sample output:

output
Last password change					: password must be changed
Password expires					: password must be changed

Common after resets or onboarding.

bash
sudo userdel -r cschage_demo
Common Password never expires (-M -1)

Service accounts often use no password rotation — set max age to -1.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -M -1 cschage_demo
sudo chage -l cschage_demo | grep -i 'password expires'

Sample output:

output
Password expires					: -1

A value of -1 means no maximum — some builds print never instead; both mean the same policy.

bash
sudo userdel -r cschage_demo
Common Set and clear account expiry date (-E)

Contractors and temp accounts get a calendar account expires date — login stops after that day.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -E 2026-12-31 cschage_demo
sudo chage -l cschage_demo | grep -i 'account expires'
sudo chage -E -1 cschage_demo
sudo chage -l cschage_demo | grep -i 'account expires'

Sample output:

output
Account expires						: Dec 31, 2026
Account expires						: never

-E 0 disables the account immediately.

bash
sudo userdel -r cschage_demo
Common Set last password change date (-d)

Adjust when the password was last changed — defer or bring forward expiry without running passwd.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -M 90 cschage_demo
sudo chage -d 2026-01-15 cschage_demo
sudo chage -l cschage_demo | grep -i 'last password'

Sample output:

output
Last password change					: Jan 15, 2026

Dates accept YYYY-MM-DD or days since 1970-01-01 per the man page.

bash
sudo userdel -r cschage_demo
Advanced ISO8601 dates in listings (-i)

When scripts parse chage -l, -i prints ISO dates instead of locale-style month names.

Run the command:

bash
sudo useradd -m cschage_demo
sudo chage -E 2026-12-31 cschage_demo
sudo chage -i -l cschage_demo | grep -i 'account expires'

Sample output:

output
Account expires						: 2026-12-31

Note: -i when listing is ISO8601 output; -I (capital) sets inactive days — different option.

bash
sudo userdel -r cschage_demo
Advanced Interactive chage session

Running chage with only a username prompts for each field. Press Enter to keep the value shown in brackets.

Run the command (non-interactive capture is not practical here). On a test user:

bash
sudo useradd -m cschage_demo
sudo chage cschage_demo

You see prompts such as:

text
Changing the aging information for cschage_demo
Enter the new value, or press ENTER for the default

Minimum Password Age [0]:
Maximum Password Age [99999]:

Press Enter through prompts to leave defaults, then verify:

bash
sudo chage -l cschage_demo
sudo userdel -r cschage_demo

Interactive mode suits one-off admin work; scripts use -M, -m, -W, and -E flags.


chage — when to use / when not

Use chage whenUse something else when
  • You need password expiry, warning, or inactivity policy
  • A temporary account needs a calendar expiry date
  • You must force change at next login (-d 0)
  • You need to set the password hash → passwd
  • You are creating the user → adduser / useradd
  • You need groups or shell → usermod
  • Central auth (LDAP/SSO) owns policy → directory tools

chage vs passwd

chage passwd
Changes Aging fields in shadow Password hash
Expiry policy Yes No
Interactive password No Yes

Run passwd to set a new password; run chage to control when it must change again.


chage — interview corner

What does chage do?

chage (change age) reads and writes password aging fields in /etc/shadow: last change date, min/max password age, warning period, inactivity lock, and account expiry. It does not change the encrypted password itself.

A strong answer is:

"chage manages shadow aging — expiry, warnings, inactivity, account date — not the password hash."

Which /etc/shadow fields does chage control?

Fields 3–8: lastchg, min, max, warn, inactive, expire. Field 2 (password hash) is untouched. Dates are stored as days since 1970-01-01 internally; CLI accepts YYYY-MM-DD for many options.

A strong answer is:

"chage edits shadow fields 3–8 — last change, min/max age, warn, inactive, expire — not the hash."

How do you force a user to change password at next login?

sudo chage -d 0 username — last password change moves to the epoch so the password is expired immediately. Login succeeds only after they set a new password (unless other locks apply).

A strong answer is:

"chage -d 0 — expired password flag; user must set a new password on next login."

What is the difference between password inactive and account expires?

-I (inactive) — days after password expiry before the account locks if the user never changed an expired password. -E (expire) — calendar date when the account is disabled regardless of password state.

A strong answer is:

"Inactive is grace after password expiry; account expires is a hard calendar cutoff for the whole account."

Who can run chage?

Only root or sudo. Regular users cannot change aging fields for themselves (some distros let users run chage -l on their own account — check policy).

A strong answer is:

"chage needs root/sudo to modify aging; it's an admin policy tool."


Troubleshooting

Symptom Likely cause Fix
user 'x' does not exist Typo or missing account getent passwd x; create user first
invalid date Bad -d or -E format Use YYYY-MM-DD
User not prompted to change password PAM or -M -1 chage -l; check LOGIN_DEFS
Account locked unexpectedly Inactivity (-I) after expiry chage -l; extend or chage -I -1
Confused -i vs -I Similar letters -i ISO listing; -I inactive days
chage -l date off by one day Timezone vs epoch storage Trust the flag value; compare with chage -i -l (ISO dates)
Changes missing in chroot Wrong system root chage -R /path/to/chroot

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Rohan Timalsina

is a technical writer and Linux enthusiast who writes practical guides on Linux commands and system administration. He focuses on simplifying complex topics through clear explanations.

  • Linux
  • HTML5
  • JavaScript
  • Web Design
  • Front-end Web Development