Fixing “Unable to Locate Credentials” Error When Running AWS CLI from Cron Jobs


1 views

Many developers encounter credential issues when transitioning from manual CLI execution to automated cron jobs. The AWS CLI works perfectly during interactive sessions but fails with "Unable to locate credentials" in cron environments. This typically stems from environment differences between user sessions and cron's restricted environment.

Cron runs commands in a minimal environment, which means:

1. No user-specific environment variables
2. Limited PATH settings
3. Different working directory
4. No shell initialization files loaded

Many attempts like these don't work:

# Doesn't work in cron:
AWS_CONFIG_FILE="~/.aws/config"

# Also ineffective:
export AWS_SHARED_CREDENTIALS_FILE=/home/user/.aws/credentials

1. Absolute Paths for Config Files

Replace the tilde with full path:

AWS_CONFIG_FILE="/home/username/.aws/config"
AWS_SHARED_CREDENTIALS_FILE="/home/username/.aws/credentials"

2. Environment Wrapper Script

Create a wrapper that sets the environment:

#!/bin/bash
export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_SHARED_CREDENTIALS_FILE="/root/.aws/credentials"
export PATH=/usr/local/bin:$PATH

/path/to/your/backup_script.sh

3. IAM Role Alternative

For EC2 instances, consider using IAM roles instead of credentials file:

# Remove credential-related lines entirely
# The CLI will automatically use the instance's IAM role

Here's a production-tested cron-compatible version:

#!/bin/bash

# Set full paths to AWS config
export AWS_CONFIG_FILE="/root/.aws/config"
export AWS_SHARED_CREDENTIALS_FILE="/root/.aws/credentials"

# Ensure PATH includes AWS CLI
export PATH=/usr/local/bin:/usr/bin:/bin:$PATH

# Main backup logic
while read -r p; do
    /usr/local/bin/aws s3 cp "$p" s3://backup-bucket/path/ \
        --recursive >> /var/log/backup.log 2>&1
done < /etc/backup/include.txt

To troubleshoot cron issues:

# Capture full environment:
env > /tmp/cronenv.log

# Test PATH availability:
which aws >> /tmp/cronpath.log 2>&1

When running as root:

  • Set strict permissions on credentials files (600)
  • Consider using dedicated IAM users with minimal permissions
  • Regularly rotate credentials

When executing AWS CLI commands via CRON, many developers encounter the frustrating "Unable to locate credentials" error despite the same commands working perfectly in interactive shell sessions. This typically occurs because CRON runs in a minimal environment that doesn't automatically load the same configuration and credentials as your user shell.

Your current approach of setting AWS_CONFIG_FILE="~/.aws/config" has three potential problems:

1. The ~ expansion doesn't work in CRON context
2. AWS CLI might need both config and credentials files
3. CRON doesn't inherit your shell's environment variables

Here are three reliable methods to make AWS CLI work in CRON:

Method 1: Absolute Paths with Full Configuration

AWS_CONFIG_FILE="/root/.aws/config"
AWS_SHARED_CREDENTIALS_FILE="/root/.aws/credentials"
export AWS_CONFIG_FILE AWS_SHARED_CREDENTIALS_FILE

while read p; do
  /usr/local/bin/aws s3 cp "$p" s3://PATH/TO/BUCKET --recursive >> /PATH/TO/LOG 2>&1
done 

Method 2: Environment File Approach

Create /etc/aws_env:

AWS_ACCESS_KEY_ID=AKIAXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
AWS_DEFAULT_REGION=us-west-2

Then modify your CRON job:

0 * * * * . /etc/aws_env; /path/to/your/script.sh

Method 3: IAM Role for EC2 (Most Secure)

If running on EC2, attach an IAM role with S3 permissions instead of using credentials files:

#!/bin/bash

# No credentials needed when using IAM roles
while read p; do
  aws s3 cp "$p" s3://PATH/TO/BUCKET --recursive >> /PATH/TO/LOG 2>&1
done 

To troubleshoot credential issues:

# Add this to your script temporarily
env > /tmp/cron_env.debug
aws configure list >> /tmp/cron_env.debug

When working with credentials in CRON jobs:

  • Set strict file permissions (600) for credentials files
  • Regularly rotate credentials
  • Consider using AWS Systems Manager Parameter Store for sensitive values
  • Limit IAM policies to only required S3 actions