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

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

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