You plan ahead, write your posts in advance, schedule them for publication — and a few days later you notice nothing was published. WordPress shows a “Missed schedule” error and your scheduled posts are still sitting as drafts.
This happened to me for several weeks. I searched online and asked around, and while I collected various hints and suggestions, nothing worked — until I found the definitive fix.
The setup used when writing this: a KVM virtual machine running in Proxmox, Debian, WordPress, and PHP. The specific versions do not matter — this solution works on current setups as well.
Here are the common causes worth checking first:
- Wrong file/folder permissions on WordPress
Your entire WordPress directory (including subdirectories and files) must be owned by the web server user, e.g.
www-datafor Apache ornginxfor Nginx — notroot. - Incorrect chmod settings
Run
sudo chmod -R 0755 /path/to/wordpress/to fix permission issues. - Plugins attempting to fix scheduling Several plugins claim to fix this, but they typically only handle post scheduling — not backup tasks or other cron jobs. None of them fixed the root issue.
- Wrong server time, date, or timezone
Install
ntp(orsystemd-timesyncd) on your Linux server to keep the clock synchronized. Make sure to run it at least once after installation. - Mismatched timezone between server and WordPress In WordPress Settings, set the date, time, and timezone to exactly match your server configuration.
- Conflict with a plugin or theme For troubleshooting, disable all plugins and custom themes to isolate the issue.
The definitive fix#
After weeks of searching, the solution turned out to be a single line added to wp-config.php.
Short version#
Add this line to wp-config.php, just before the /* That's all, stop editing! Happy blogging. */ comment:
define('ALTERNATE_WP_CRON', true);Restart your web server and scheduling will work again.
Why this works#
If your WordPress is running behind a router or firewall (such as pfSense or OPNsense), missed schedules may not be caused by a problem on the machine itself — they are caused by your network architecture.
WordPress runs scheduled tasks by making an HTTP request to itself via wp-cron.php. If your router or firewall blocks loopback requests (requests from the server to itself), WordPress can never execute those scheduled tasks.
Setting ALTERNATE_WP_CRON to true changes how WP-Cron is triggered: instead of relying on a loopback HTTP request, it uses a redirect-based mechanism that bypasses the loopback restriction.
Security note (shared hosting or Apache)#
Enabling ALTERNATE_WP_CRON adds a doing_wp_cron query string parameter to some URLs. To prevent any potential abuse, add the following rewrite rule to the .htaccess file at the root of your WordPress site:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (^|&)doing_wp_cron= [NC]
RewriteRule (.*) /$1? [R=301,L]This strips the parameter from the URL, preventing it from being visible or exploited externally.