What cron actually gives you
Add this to your crontab temporarily to see exactly what environment cron provides:
* * * * * env > /tmp/cron-env.txt
Wait one minute, then look at /tmp/cron-env.txt. Typical output:
HOME=/home/yourname LOGNAME=yourname PATH=/usr/bin:/bin SHELL=/bin/sh PWD=/home/yourname LANG=...
That's it. Nothing else. No AWS_PROFILE, no DATABASE_URL, no NVM-managed Node, no Python virtualenv.
Fix 1: Set PATH in the crontab
At the top of your crontab, before any job entries:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin SHELL=/bin/bash 0 9 * * * /home/me/script.sh
This applies to ALL jobs in that crontab. Now things like python3 (usually in /usr/local/bin) work.
Fix 2: Use absolute paths in scripts
#!/bin/bash # Don't depend on PATH at all /usr/local/bin/python3 /opt/myapp/main.py
This is the most reliable approach — never relies on environment, works even from a stripped-down init.
Fix 3: Source your env file
If you have a lot of env vars (AWS credentials, database URLs, API keys), put them in a file and source it at the start of the script:
# /etc/cron-env/myapp (chmod 600, only readable by the user) export AWS_PROFILE=production export DATABASE_URL="postgres://..." export API_KEY="..." # In your script: #!/bin/bash source /etc/cron-env/myapp # ... rest of script ...
Keep secrets out of the crontab itself — anyone who can read it (including with ps) sees the values.
Fix 4: For Node Version Manager (nvm)
nvm is loaded from ~/.nvm/nvm.sh which is only sourced by your shell. Under cron, you need to load it explicitly:
#!/bin/bash export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm use --silent 18 node /path/to/script.js
Fix 5: For Python virtualenvs
#!/bin/bash source /opt/myapp/venv/bin/activate python /opt/myapp/main.py
Or call the venv's python directly:
/opt/myapp/venv/bin/python /opt/myapp/main.py
Common error messages and what they mean
| Error | Cause |
|---|---|
python3: command not found | PATH doesn't include /usr/local/bin |
node: command not found | nvm not loaded; use absolute path |
aws: command not found | AWS CLI installed in non-standard location |
ModuleNotFoundError: No module named 'X' | Python virtualenv not activated |
command not found: source | Shell is /bin/sh (dash), not bash — set SHELL=/bin/bash |