Solving “Authentication Token Expired” Error for Passwordless Users in Linux Cron Jobs


5 views

When managing Linux systems, we occasionally encounter situations where users need to operate without passwords (perhaps for automation purposes). The classic passwd -d username command seems like a straightforward solution, but it introduces subtle authentication challenges.

Even with a deleted password, Linux maintains PAM (Pluggable Authentication Modules) security tokens. These tokens get invalidated according to the system's password aging policy, typically every 30 days. The system doesn't distinguish between passwordless users and regular users in this regard.

# Typical error seen in cron logs
Authentication token is no longer valid; new one required
ERROR: failed to open PAM security session: Success
ERROR: cannot set security context

Here are several approaches to resolve this issue, ranked from simplest to most complex:

1. Disable Password Aging for the User

sudo chage -I -1 -m 0 -M 99999 -E -1 username

This prevents the authentication token from expiring by:

  • -I -1: Sets password inactivity to never
  • -m 0: Minimum days between changes to 0
  • -M 99999: Maximum password age to ~273 years
  • -E -1: Account expiration to never

2. Configure PAM to Ignore Token Expiration

Edit /etc/pam.d/cron and modify the auth line:

# Change from:
auth required pam_unix.so

# To:
auth sufficient pam_unix.so likeauth nullok

The nullok option allows empty passwords, while sufficient makes authentication optional.

3. Use Systemd Timers Instead of Cron

Create a systemd service and timer that doesn't enforce PAM authentication:

# /etc/systemd/system/mycronjob.service
[Unit]
Description=My Cron Job

[Service]
Type=simple
User=username
ExecStart=/path/to/script.sh

# /etc/systemd/system/mycronjob.timer
[Unit]
Description=Run my job daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

The underlying issue stems from Linux's security model. Even without a password, the system maintains a shadow database entry for the user. The PAM stack still validates authentication tokens against this entry, following the system's password policy.

When examining /etc/shadow, you'll notice passwordless users still have an entry:

username::18659:0:99999:7:::

The empty field between colons indicates no password, but the remaining fields still control password aging policies.

For long-running automation tasks, consider creating a proper service account with restricted permissions instead of modifying existing user accounts:

sudo useradd -r -s /usr/sbin/nologin svc_automation
sudo passwd -d svc_automation
sudo chage -m 0 -M 99999 -I -1 -E -1 svc_automation

The -r flag creates a system account with more lenient default security policies.


When you delete a user's password using passwd -d in Linux, you might encounter an unexpected behavior with cron jobs. The system still enforces password expiration policies, causing authentication failures every 30 days (default PAM policy) with errors like:

Authentication token is no longer valid; new one required
ERROR: failed to open PAM security session: Success
ERROR: cannot set security context

Even without a password, Linux maintains authentication tokens through PAM (Pluggable Authentication Modules). The system still tracks "password aging" for account security, regardless of whether a password exists.

Here are three approaches to resolve this:

1. Disable Password Aging

Use chage to modify password expiration settings:

sudo chage -I -1 -m 0 -M 99999 -E -1 username

This command:

  • -I -1: Sets password inactivity to never
  • -m 0: Minimum days between changes to 0
  • -M 99999: Maximum days before change to ~273 years
  • -E -1: Account expiration to never

2. Modify PAM Configuration

Edit /etc/pam.d/crond (RHEL/CentOS) or /etc/pam.d/cron (Debian/Ubuntu):

# Replace this line:
auth required pam_unix.so

# With:
auth sufficient pam_unix.so likeauth nullok

3. System Account Conversion

For service accounts, consider making it a true system account:

sudo usermod -r username

Create a verification script to check token status:

#!/bin/bash
USER="your_username"
if sudo -U $USER true 2>&1 | grep -q "Authentication token"; then
    echo "Token expired - running chage"
    sudo chage -I -1 $USER
fi

For more secure automation, consider switching to SSH key-based authentication:

# Generate key pair
ssh-keygen -t ed25519 -f ~/.ssh/cron_key -N ""

# Add to authorized_keys
cat ~/.ssh/cron_key.pub >> ~/.ssh/authorized_keys

# Use in cron with:
* * * * * ssh -i ~/.ssh/cron_key localhost "your_command"

Remember that removing password aging reduces security auditing capabilities. Always document these changes in your system configuration logs.