The Problem
Moodle cron was failing with the error:
!!! Invalid permissions detected when trying to create a directory. Turn debugging on for further details. !!!
At the same time, the LMS was sending repeated task failure emails, including failed scheduled tasks and ad hoc task errors.
Clearing Moodle cache folders fixed the LMS temporarily, but the issue kept coming back.
Common Temporary Fix
Clearing Moodle cache folders may bring the LMS back temporarily:
sudo rm -rf /var/moodledata/cache/*
sudo rm -rf /var/moodledata/localcache/*
sudo rm -rf /var/moodledata/temp/*
sudo rm -rf /var/moodledata/muc/*
Then reset permissions:
sudo chown -R www-data:www-data /var/moodledata
sudo find /var/moodledata -type d -exec chmod 2770 {} \;
sudo find /var/moodledata -type f -exec chmod 660 {} \;
However, if the issue returns, then the root cause is likely elsewhere.
Step 1: Confirm Moodle Data Directory Settings
Check Moodle’s config.php:
sudo grep -nE "dataroot|directorypermissions" /var/www/moodle/config.php
Expected configuration:
$CFG->dataroot = '/var/moodledata';
$CFG->directorypermissions = 02770;
Avoid using:
$CFG->directorypermissions = 0777;
Step 2: Ensure Moodle Cron Runs as www-data
Moodle cron should not run as root.
Check root cron:
sudo crontab -l
If Moodle cron is there, comment it out:
#*/1 * * * * /usr/bin/php /var/www/moodle/admin/cli/cron.php >/dev/null 2>&1
Then add Moodle cron under www-data:
sudo crontab -u www-data -e
Use:
*/1 * * * * flock -n /var/moodledata/moodlecron.lock /usr/bin/php /var/www/moodle/admin/cli/cron.php >/dev/null 2>&1
This ensures Moodle cron runs using the same user as the web server.
Step 3: Test Cron Manually
Run:
cd /tmp
sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php
If the error remains, continue to the next step.
Step 4: Use strace to Find the Exact Failed Directory
Install strace if it is not already installed:
sudo apt-get update
sudo apt-get install -y strace
Run Moodle cron through strace:
cd /tmp
sudo -u www-data strace -ff -s 300 \
-e trace=mkdir,mkdirat,openat,creat,chmod,chown \
-o /tmp/moodlecron.trace \
/usr/bin/php /var/www/moodle/admin/cli/cron.php
Then search for permission errors:
sudo grep -R "EACCES\|EPERM\|Permission denied" /tmp/moodlecron.trace* | tail -100
In this case, the real error was:
mkdir("/tmp/requestdir/gLEy", 02770) = -1 EACCES (Permission denied)
This showed that Moodle was failing to create a temporary directory under:
/tmp/requestdir
Step 5: Fix the Temporary Directory
Remove the bad temporary directory and recreate it with the correct owner:
sudo rm -rf /tmp/requestdir
sudo -u www-data mkdir -p /tmp/requestdir
sudo chmod 2770 /tmp/requestdir
sudo chown www-data:www-data /tmp/requestdir
Test that www-data can write to it:
sudo -u www-data mkdir /tmp/requestdir/test-wwwdata
sudo -u www-data rmdir /tmp/requestdir/test-wwwdata
Step 6: Run Cron Again
cd /tmp
sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php
Then purge Moodle caches:
sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/purge_caches.php
Run cron again:
sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php
If it runs without the permissions error, the issue is resolved.
Recommended Permanent Configuration
To reduce future issues with /tmp, configure Moodle to use its own temp directory.
Edit:
sudo nano /var/www/moodle/config.php
Add before require_once(__DIR__ . '/lib/setup.php');:
$CFG->tempdir = '/var/moodledata/temp';
Ensure the directory exists:
sudo mkdir -p /var/moodledata/temp
sudo chown -R www-data:www-data /var/moodledata/temp
sudo chmod 2770 /var/moodledata/temp
Root Cause
The issue was caused by Moodle trying to create a directory inside:
/tmp/requestdir
but the www-data user did not have permission to write there.
This likely happened because Moodle cron had previously been running as root, creating temporary folders that later blocked Moodle when cron was correctly moved to www-data.
Final Checklist
Use this checklist to avoid the issue recurring:
# Moodle data ownership
sudo chown -R www-data:www-data /var/moodledata
# Moodle data directory permissions
sudo find /var/moodledata -type d -exec chmod 2770 {} \;
# Moodle data file permissions
sudo find /var/moodledata -type f -exec chmod 660 {} \;
# Moodle cron should run as www-data
sudo crontab -u www-data -l
# Test cron manually
sudo -u www-data /usr/bin/php /var/www/moodle/admin/cli/cron.php
so…
If Moodle shows:
Invalid permissions detected when trying to create a directory
do not only check /var/moodledata. Also check temporary paths such as /tmp.
In this case, the solution was to identify the exact failed path using strace, repair /tmp/requestdir, and ensure Moodle cron runs as www-data.