Linux 126Medium

Cron Permission Denied in Linux: Causes and Quick Fix

The 'Permission denied' error in cron tasks occurs due to insufficient permissions on scripts or log files. In this article, you'll find proven methods to configure permissions and restore the scheduler's operation.

Updated at April 6, 2026
5-10 min
Easy
FixPedia Team
Применимо к:Ubuntu 22.04/24.04Debian 11/12RHEL 8/9CentOS 7/8

What the 'Permission denied' Error Means in cron

The Permission denied error (exit code 126 or 1) appears when the cron service attempts to execute a scheduled task, but the operating system blocks access to a file, directory, or resource. In reports, you will see lines like /bin/sh: 1: /path/to/script.sh: Permission denied or Failed to execute: Permission denied.

The scheduler runs in the background, under a specific user's identity, without an interactive terminal and with a limited set of environment variables. If the script or output file requires permissions that the cron daemon does not have, execution is halted immediately at startup.

Common Causes

  1. Missing execute bit on the script itself. The file may be readable but not marked as executable.
  2. Use of relative paths in the crontab or within a bash script. cron does not inherit the standard PATH from your profile.
  3. Incorrect ownership permissions on logs or temporary files that the script attempts to write data to.
  4. Strict security policies (SELinux, AppArmor) that block the execution of non-standard binaries or access to specific directories.
  5. Attempting to run a task from the system crontab without specifying a user. In /etc/crontab and /etc/cron.d/, an explicit username is required before the command.

Solutions

Solution 1: Setting Execute Permissions on the File

Check the current permissions on your script:

ls -l /opt/scripts/backup.sh

If the first column lacks an x symbol (e.g., -rw-r--r--), add it:

chmod +x /opt/scripts/backup.sh

💡 Tip: Ensure the interpreter specified in the shebang (#!/bin/bash or #!/usr/bin/env python3) is also readable and executable by the user under which the task runs.

Solution 2: Replace Relative Paths with Absolute Ones

cron runs commands in a clean environment. If your crontab contains backup.sh or the script uses ./config.ini, the system will not find the file or will deny access to the current directory.

Replace all paths with full ones:

# Incorrect for cron
0 2 * * * my_script.sh

# Correct
0 2 * * * /usr/local/bin/my_script.sh

Inside the script itself, specify full paths to utilities explicitly:

#!/bin/bash
/usr/bin/rsync -avz /home/user/data /mnt/backup
/usr/sbin/logrotate /etc/logrotate.d/myapp

Solution 3: Configuring Permissions for Logs and Working Directories

A common cause of the error is an attempt to write command output (>> /var/log/cron.log) to a directory where the user lacks write permissions. Cron runs tasks under the identity of the crontab owner, so target directories must belong to that user:

sudo chown -R user:user /var/log/myapp
sudo chmod 755 /var/log/myapp

If you use output redirection in the crontab:

# Runs as user www-data, logs errors
*/15 * * * * www-data /usr/local/bin/fetch-data.sh >> /var/log/myapp/fetch.log 2>&1

Verify that the /var/log/myapp directory exists and is writable by the www-data user.

Solution 4: Checking Security Policies (AppArmor / SELinux)

On modern distributions, standard chmod permissions may be insufficient. If the system is protected by AppArmor (Ubuntu/Debian) or SELinux (RHEL/Alma/Rocky), they may silently block execution.

Check AppArmor status:

aa-status | grep my_script.sh

If the profile is in enforce mode, switch it to complain for testing:

sudo aa-complain /usr/local/bin/my_script.sh

For SELinux, use audit2why to analyze blocks:

sudo ausearch -m avc -ts recent | audit2why

Once a block is confirmed, add an exception or update policies via semodule.

Prevention

  • Test in a clean environment. Before adding to cron, run the script with env -i bash /path/to/script.sh. This mimics cron's empty environment and immediately reveals issues with paths or variables.
  • Use sudo -u. To test execution permissions, run sudo -u target_user /path/to/script.sh. This shows the actual task restrictions before scheduling.
  • Configure notifications. Add MAILTO="admin@example.com" at the top of your crontab so the system automatically sends error reports via email.
  • Lock down paths in scripts. Add set -euo pipefail at the beginning of each bash script. This forces execution to stop on the first permission error or missing command, simplifying debugging.

F.A.Q.

Why does cron return permission denied even though the script runs manually?
Can cron tasks be run as root without errors?
How to enable detailed cron logging for debugging?

Hints

Check and set execute permissions
Convert paths to absolute
Set permissions for working directories
Check security policies

Did this article help you solve the problem?

FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community