Unit

Understanding the /etc/shadow File Format

Learn the nine /etc/shadow fields, password hashes, lock markers, aging policies, permissions, PAM behavior, and safe Linux administration commands.

/etc/shadow is the protected local Linux account database for password-verifier data and password-aging policy. It normally contains one record for each local account. Understanding its format helps administrators diagnose login problems and configure account policies safely.

This file contains sensitive authentication data. Read it only when necessary, avoid copying its contents into tickets or chat, and prefer account-management commands over manual editing.

What /etc/shadow Is Used For

A password hash is a one-way verifier derived from a password. During password authentication, the system processes the supplied password and compares the result with the stored verifier. The original password is not stored in /etc/shadow.

The file also stores password aging values: when the password was last changed, how long it must remain unchanged, when it expires, how long to warn the user, and when an inactive account should be disabled.

Aspect/etc/passwd/etc/shadow
Primary purposeAccount identity and profile informationPassword verifiers, account markers, and password-aging data
Typical fieldsUsername, UID, GID, comment, home directory, login shellUsername, password field, aging and expiration fields
Typical accessUsually readable by all users so programs can map names and IDsRestricted to root and, on some systems, an authorized shadow group
Password storageUsually contains x as a reference to the shadow databaseContains the verifier or a password-account marker

Separating password verifiers from the generally readable account database reduces exposure. Programs can discover usernames and numeric IDs without receiving the data needed to test passwords offline. File permissions do not replace strong passwords, secure hashing algorithms, patching, monitoring, and other authentication controls.

Permissions and Safe Access

Typical systems make /etc/shadow root-owned and restrict reading and writing to root, sometimes granting read access to a dedicated shadow group. Exact ownership and mode vary by distribution and installation. Inspect permissions without displaying file contents:

ls -l /etc/passwd /etc/shadow

Direct editing is risky because a single missing colon, malformed number, mismatched username, or truncated hash can break account administration or authentication. For normal work, use passwd, chage, or usermod. If direct maintenance is absolutely unavoidable, vipw -s provides locking and safer editing behavior:

sudo vipw -s

Before low-level changes, establish a protected backup and a recovery plan. Validate syntax and test with a nonproduction account. Treat a backup of this file as highly sensitive: anyone who obtains password hashes may attempt offline guessing.

Record Layout

Each non-comment record uses nine logical fields separated by colons. The following is a syntax diagram, not a literal system record:

login:password-field:last-change:min-age:max-age:warning:inactive:account-expiry:reserved

A fictional annotated example is shown below. The password-verifier content is intentionally represented by a neutral placeholder:

demo_user:[redacted-verifier]:19800:1:90:14:30:20000:
  1. demo_user — login name.
  2. [redacted-verifier] — a password hash or account marker.
  3. 19800 — day of the last password change.
  4. 1 — minimum days before another password change.
  5. 90 — maximum password age.
  6. 14 — warning days before expiration.
  7. 30 — inactive days after password expiration.
  8. 20000 — absolute account-expiration day.
  9. Empty final field — reserved field.

The Nine /etc/shadow Fields

PositionField nameTypical contentsMeaningCommon blank or marker behavior
1Login nameUsernameIdentifies the local account and corresponds to an entry in /etc/passwd.Should not be blank for a normal account. Records should align with local account entries.
2Password fieldHash or markerStores a one-way verifier or indicates a password state.Empty can mean no password is set; * commonly makes password authentication unusable; leading ! commonly locks a hash.
3Last password changeDay countDays since the Unix epoch when the password was last changed.Blank handling varies. Some tools interpret blank or special values as no recorded change.
4Minimum password ageDay countMinimum number of days before the user may change the password again.Blank or zero commonly means no minimum, subject to the tool and policy.
5Maximum password ageDay countMaximum number of days the password remains valid.Blank or a large value may mean no local expiration, depending on implementation.
6Warning periodDay countNumber of days before expiration during which warnings are given.Blank or zero may disable a warning period.
7Inactivity periodDay countDays after password expiration before the account is disabled for inactivity.Blank commonly means no inactivity limit; verify with policy tools.
8Account expirationDay countAbsolute date after which the account cannot authenticate under the applicable policy.Blank commonly means no local expiration date.
9ReservedUsually emptyReserved for future use.Ordinarily left empty.

Field 1: Login Name

The first field is the username used to identify the account. It should correspond to the account name in /etc/passwd. A mismatch can cause tools to report incomplete account data or cause authentication behavior to differ from expectations. Local accounts should have consistent entries in the local account databases.

Field 2: Password Hashes and Account Markers

A normal password field contains a modular crypt format value. Modular crypt format is a structured representation that commonly includes an algorithm identifier, parameters or cost settings, a salt, and the resulting hash:

$algorithm$parameters$salts-and-hash

A salt is a per-password value included in hashing. It prevents identical passwords from normally producing identical stored outputs and makes precomputed lookup attacks less useful. The value is still a verifier, not an encrypted password that administrators can decode.

Prefix or markerTypical interpretationSecurity and compatibility notes
$1$MD5 cryptObsolete and unsuitable for new passwords.
$5$SHA-256 cryptOlder crypt-family format; use the distribution's current policy rather than selecting it manually.
$6$SHA-512 cryptCommon legacy crypt-family format, but not necessarily the default on modern systems.
$y$yescrypt, where supportedA modern memory-hard scheme used by some contemporary distributions.
Leading !Password entry commonly lockedOften placed before an existing hash. Exact behavior depends on PAM and distribution policy.
*Password authentication commonly unusableOften used for service or system accounts. Other authentication methods may still be possible.
Empty fieldNo password verifierMay permit passwordless authentication if the service and PAM configuration allow it; this is generally unsafe and must not be confused with a locked hash.

Locking a password usually preserves the existing hash while adding a lock marker, such as a leading exclamation mark. Deleting the hash, often by making the field empty, is different: it removes the verifier rather than merely disabling the existing password. Neither state alone describes every possible login path. SSH keys, service rules, PAM modules, MFA, and centrally managed identities can continue to affect access.

Password Aging Fields

Fields 3 through 8 generally use whole days since the Unix epoch, which begins on 1970-01-01 UTC. These are date-only policy values, not ordinary timestamps.

FieldUnitPolicy effectExample interpretation
Last password changeDays since epochRecords the reference point for password age.A value of 19800 identifies the day on which the password was last changed.
Minimum ageDaysPrevents another password change until this many days have passed.1 means the user normally waits one day.
Maximum ageDaysSets when the password becomes expired.90 means expiration is evaluated 90 days after the last change.
Warning periodDaysControls how early expiration warnings begin.14 means warnings can begin 14 days before expiration.
Inactive periodDays after expirationDisables the account after an expired password remains unused for this interval.30 means disablement can follow 30 inactive days after expiration.
Account expirationDays since epochSets an absolute account expiration date independent of password age.A value such as 20000 identifies a fixed calendar day.

The minimum and maximum ages govern password age. The inactive interval starts after password expiration. Account expiration is a separate absolute boundary. Blank values, zero values, and very large values can have tool-specific meanings, so inspect the interpreted result with account-management commands.

Converting Shadow Day Counts

On systems with GNU date, convert an illustrative day count to a UTC date as follows:

DAY_COUNT=19800
date -u -d "1970-01-01 + $DAY_COUNT days" +%F

The result is a UTC calendar date. Other Unix-like systems use different date syntax. Because shadow values represent whole days and policy dates are not timestamps, avoid treating a local-time conversion as more precise than the stored data.

For a human-readable interpretation, use:

sudo chage -l USERNAME

This can show the last password change, password expiration, minimum and maximum ages, warning period, inactivity period, and account expiration without requiring you to expose the raw hash.

Account-Management Tools

TaskPreferred command or toolWhy it is preferredVerification method
Set or change a passwordsudo passwd USERNAMEUpdates the verifier through supported mechanisms and policy.sudo passwd -S USERNAME and sudo chage -l USERNAME
Display aging policysudo chage -l USERNAMEShows interpreted dates and intervals without manual arithmetic.Review the displayed policy.
Set aging valuessudo chage ... USERNAMEValidates and updates the relevant fields.Run chage -l again.
Lock password authenticationsudo passwd -l USERNAME or an appropriate usermod lock operationApplies a standard lock state without hand-editing the hash.sudo passwd -S USERNAME
Unlock password authenticationsudo passwd -u USERNAMERemoves a supported lock marker when a valid hash and policy permit it.Check status and test the intended service.
Direct shadow maintenancesudo vipw -sProvides file locking and a controlled editing workflow.Run account tools and perform controlled validation.

Example: Configure a Demonstration Policy

Use this only for a test or nonproduction account and adapt it to organizational policy:

sudo chage -M 90 -m 1 -W 14 -I 30 USERNAME
sudo chage -l USERNAME

To set an absolute account expiration date:

sudo chage -E YYYY-MM-DD USERNAME

passwd -S provides compact status information that can help distinguish a usable password, a locked password, and a passwordless or otherwise unusable state. Its exact output format varies by implementation, so use chage -l and service logs for details.

/etc/shadow, PAM, and Authentication Paths

Local Unix authentication commonly reads /etc/shadow through PAM, or Pluggable Authentication Modules. PAM is a framework that lets services apply authentication, account, password, and session rules through configured modules.

A shadow entry is only one input to an authentication decision. PAM rules, SSH configuration, login-shell restrictions, MFA, access-control policy, directory services, and service-specific settings can change the result. A local password is also different from:

  • SSH public-key authentication: the client proves possession of a private key; it may work even when password authentication is locked, if SSH policy permits it.
  • Centrally managed identities: LDAP, SSSD, or another identity provider may supply account and password data instead of the local files.
  • Other authentication methods: hardware tokens, certificates, or MFA can be evaluated by PAM or the service.

Locking Versus Expiring

sudo passwd -l USERNAME normally disables password-based authentication by marking the password field while retaining the verifier. This is useful for temporarily suspending password login or disabling a known password path without deleting its data.

sudo chage -E YYYY-MM-DD USERNAME sets an absolute account expiration date. This applies an account-policy boundary and is not the same as locking only the password. Use a password lock when the password method should be disabled; use account expiration when the account itself should stop authenticating after a defined date. Always consider keys, PAM rules, and external identity sources.

Safe Inspection and Administration Workflow

  1. Confirm whether the account is local and identify the service involved.
  2. Use sudo chage -l USERNAME and sudo passwd -S USERNAME before reading raw shadow data.
  3. Use passwd, chage, or usermod for supported changes.
  4. Record the authorized change, intended effect, and recovery procedure.
  5. For exceptional direct maintenance, make a protected backup and use sudo vipw -s, not an unrestricted text editor.
  6. Verify field structure, ownership, permissions, account-tool output, and the intended login method.
  7. Check relevant authentication logs without disclosing password hashes.

Privileged access is normally required to read the shadow database or change another user's password and policy. A regular user can usually change their own password, subject to local policy, but cannot normally inspect other users' verifiers.

Troubleshooting Common Problems

A user cannot log in after the account was locked

  • Check status with sudo passwd -S USERNAME.
  • Check expiration and inactivity with sudo chage -l USERNAME.
  • Review the relevant service logs and PAM policy.
  • If password login should be restored, use sudo passwd -u USERNAME rather than removing a marker by hand. Confirm that a valid hash remains.

The user is told that the password has expired

  • Review the maximum age and last-change date with chage -l.
  • Check whether a PAM or organizational policy imposes additional expiration.
  • Reset the password when authorized, then change aging values with chage h only if policy requires it.

Manual editing broke account tools or login

  • Possible causes include an incorrect colon-field count, malformed numeric values, a username mismatch, or a truncated hash.
  • Restore a known-good protected backup if available.
  • Use supported account tools or a controlled recovery procedure; do not guess at hash contents.
  • For future exceptional edits, use vipw -s.

Password login fails despite a valid-looking hash

  • The account may be expired or inactive.
  • The login shell or service may deny access.
  • SSH may disallow password authentication while allowing keys.
  • PAM, MFA, or an external identity provider may override local expectations.
  • Check chage -l, passwd -S, service configuration, logs, and the account's identity source before changing the hash.

Key Exam and Administration Notes

  • /etc/passwd is primarily the readable identity database; /etc/shadow protects password verifiers and aging data.
  • There are nine colon-separated logical fields.
  • Fields 3 through 8 generally count days from the Unix epoch.
  • A leading ! commonly locks an existing password hash; an empty password field is a different state.
  • $1$ identifies obsolete MD5 crypt. $5$ and $6$ identify SHA-256 crypt and SHA-512 crypt; $y$ identifies yescrypt where supported.
  • Use passwd, chage, and usermod instead of editing the file directly.
  • A shadow entry does not by itself determine whether SSH keys, PAM modules, MFA, or centralized identities can authenticate.

For related local account administration, see creating a Linux user, administering groups, and modifying file permissions.