How to fix the Missed Schedule Post Error

Missed schedule posts are a common error in WordPress. Sometimes people experience issues with the scheduled posts, particularly not been published. After hours have passed and the posts remain unpublished, people login to their site, go to the post edit page and select update to manually publish said posts.

wp missed schedule posts

However this is not a solution, merely a workaround the problem. The good news is it’s almost never a wordpress installation issue, but a hosting environment problem. The bad news is in order to fix the problem, access to the site directory and even server control are required. Still there are some trouble-free errors that are not quite so demanding.

100 posts limit

The first thing we need to do is make sure there aren’t more than 100 posts in the schedule queue. WordPress has a built-in limit of 100 scheduled posts. Any posts scheduled beyond that amount will not be published, so temporary move to trash all the posts beyond that limit.

Wp-cron is disabled

At a previous date you may have disabled the wp cron. Open wp-config.php for editing and look for the line:

define('DISABLE_WP_CRON', true);

You can either comment it or change true to false in order to re-enable the standard wp cron.

Not enough traffic

Wp-cron is not a real linux system cron per-se. It is a time-based task scheduling system, but it runs only on page load. So if you have posts scheduled to be publish at 1 PM and nobody visits your site until 4 PM, the posts will not be published until then. Fear not though, the posts will remain in a queue and will be posted as soon as a page load is requested. If this behavior is not suited for you and you have access to your hosting system, you can force wp-cron to be run by the system’s cron. First disable wordpress from running the wp-cron on page load by adding

define('DISABLE_WP_CRON', true);

to your wp-config.php file. It is best to add it close to the beginning of the file to prevent conflicts. Then use

crontab -e -u www-data

to edit the system schedule for user www-data (note: www-data must be the user that actually runs the php files on your system, it can be nginx, apache or even your own username). Now enter this line to run the wp-cron every 10 minutes:

*/10 * * * * wget http://YOUR_SITE_URL/wp-cron.php

More information about setting the intervals at which wp-cron will run can be found on WordPress cron page.

From now on we are going to focus on more complicated issues. Access to the hosting environment will be required as well as some knowledge about server logging. It is best to locate your access and error logs first. Usually you can find them in /usr/local/var/log/nginx/ or /var/log/httpd/, depending on having nginx or apache as your web server.

WP-Cron Status Checker

wp cron status checker

WP-Cron Status Checker(link) is a great plugin for our endeavour. It regularly checks if WordPress can run the WP-Cron system. It does not check if the scheduled tasks are well designed or if they fail. We are going to use from now on to see the various errors wp-cron throws at us. You can see the plugin’s results on your wordpress admin dashboard.

Error 503

wp cron error 503

Sometimes i like to turn my website into maintenance mode so i can do little tweaks or database backups. And i do that directly in nginx config or .htaccess, preventing every ip address, but my own from seeing a real live version of my website. It goes something like this:

if ($remote_addr != "188.25.111.207") {
return 503;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.php last;
}

for nginx, or for apache:

RewriteCond %{REMOTE_HOST} !188.25.111.207
RewriteCond %{REQUEST_URI} !/maintenance.php$
RewriteRule $ /maintenance.php [R=302,L,NE]

188.25.111.207 being my personal ip address. However when i put my site in maintenance, my scheduled posts would not publish at all. Checking the access.log brings forward lines like:

108.61.117.195 - - [01/Mar/2017:18:36:36 +0100] "POST /wp-cron.php?doing_wp_cron=1488562596.8412280082702636718750 HTTP/1.1" 503 127 "http://www.thewp.info/wp-cron.php?doing_wp_cron=1488562596.8412280082702636718750" "WordPress/4.7.2; http://www.thewp.info"

What we can see here is that the wp-cron.php is trying to execute from our own site ip (108.61.117.195), but the maintenance settings prevent it from running. So lets add the site ip address to the rules so local scripts can be executed. For apache it is as easy as cake: just add RewriteCond %{REMOTE_HOST} 108.61.117.195 at the top of our existing code resulting in

RewriteCond %{REMOTE_HOST} !108.61.117.195
RewriteCond %{REMOTE_HOST} !188.25.111.207
RewriteCond %{REQUEST_URI} !/maintenance.php$
RewriteRule $ /maintenance.php [R=302,L,NE]

However for nginx it’s a little more complicated since it does not allow ‘and’ nor ‘or’ inside a IF clause. So we must use a little trick to get the same result:

if ($remote_addr != "188.25.111.207") {
set $test P;
}
if ($remote_addr != "108.61.117.195"){ # server ip
set $test "${test}C";
}
if ($test = PC) {
return 503;
}

# error 503 redirect to 503_on.php
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.php last
}

Unexpected HTTP response code: 404

wp cron error 404

WOW! This error is quite .. unexpected: 404 means the file isn’t there. If you get a 404 response when you access www.your-site-url/wp-cron.php from your personal computer as well then your wp-cron.php must be missing. However if the response is different, it means the localhost of the server views a different version of the site than the rest of the world. The solution is to delete / un-comment lines like listen 80 default_server; and listen [::]:80 default_server; from your nginx.conf or conf.d/default.conf files leaving only

listen 80;
server_name localhost;

Error 499 / 500

wp cron error 499

If you happen to find your access log spammed with lines like this one:

108.61.117.195 - - [01/Mar/2017:18:39:33 +0100] "POST /wp-cron.php?doing_wp_cron=1488562596.8412280082702636718750 HTTP/1.1" 499 103 "http://www.thewp.info/wp-cron.php?doing_wp_cron=1488562596.8412280082702636718750" "WordPress/4.7.2; http://www.thewp.info"

you need to force the web server not to abort the connection when the user leaves your page. You can accomplish this by editing your php.ini file, the apache httpd.conf or nginx.conf file. For php.ini and httpd.conf add (or change)

ignore_user_abort = On

while for nginx your need to add

fastcgi_ignore_client_abort on

cURL error 7: Failed connect to

This error appears mostly when you have many posts in the schedule queue. It means the wp-cron is not able to process all the information in a timely manner. You must increase the script execution time in php.ini using the max_execution_time directive, but make sure to not overdo it. max_execution_time = 60 is an ok-ish value to work with. Furthermore it is imperative to increase your keepalive_timeout in nginx.conf, use a value close to 60 seconds:

keepalive_timeout 60s;

upstream timed out (110: Connection timed out)

It is quite uncommon to run into this problem. But if you are checking the error.log and see upstream timed out (110: Connection timed out) make sure to add

upstream proxy_http_version 1.1;
proxy_set_header Connection "";

to make your wp-cron work flawlessly.

Conclusion

The WordPress team has managed to fine tune the wp-cron quite well. ‘Missed Schedule’ posts error or other problems arise due to your hosting setup. Make sure to check on your access.log and error.log to fix wp cron errors. We will update this post whenever we are notified of other error response codes.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *