I get this PHP Warning when accessing my fresh WordPress 3.4.1 install (Norwegian language).
Warning: fopen(URL_TO_MY_WORDPRESS_PAGE/wp-cron.php?doing_wp_cron=1341476616.7605190277099609375000): failed to open stream: Connection timed out in PATH_TO_MY_WP_FILES/wp-includes/class-http.php on line 923
This is of course with the
WP_DEBUG flag set to
true, as it’s running on a development server.
This happens intermittently, so it seems to be a problem with
Is this likely an error in WordPress or something wrong on my server? Should I worry?
The server is a fresh Ubuntu Server 12.04 VM with the LAMP stack.
Google search shows I’m not the only one experiencing this. (See buffered/indexed versions of pages listed to see the actual errors.)
EDIT: I’m also getting this same PHP Warning on the front page. Could it be related to the fact that the webserver is being NATed to? Currently I’ve set up the firewall to point port 19235 to 80 on the development server.
The answer is apparently YES, I should worry. After some research, I’ve found that the warning seems to be related to misconfigurations on the server that WordPress is hosted on (ie. a problem with my server, not WordPress).
The problem in my case was actually caused by my firewall (pfSense), which has “Disable NAT reflection” by default (listed as common reason #2).
On the server itself, I tried to reach myself using telnet, and the result was as follows:
$ telnet external.server.hostname.com 19235 Trying XXX.XXX.XXX.XXX... telnet: Unable to connect to remote host: Connection timed out
To fix this, I had to uncheck Disable NAT reflection on my firewall. In my case, this was in the web interface of pfSense under System->Advanced->Firewall/NAT.
Now I can connect to myself (on the server itself) through the firewall just fine:
$ telnet external.server.hostname.com 19235 Trying XXX.XXX.XXX.XXX... Connected to external.server.hostname.com. Escape character is '^]'.
and I am no longer getting the PHP warning about wp-cron.
I figured this out after reading this detailed answer regarding
wp_cron, explaining how it works.
Short answer: Add this to the defines in your wp-config.php file:
Really long answer, for masochists: Scheduled posts are not now, and
have never been, “broken”. The developers of WordPress cannot fix it
because there is nothing to fix.
The problem lies in the fact that your server, for some reason, cannot
properly execute the wp-cron process. This process is WordPress’
timing mechanism, it handles everything from scheduled posts to
sending pingbacks to XMLRPC pings, etc.
The way it works is pretty simple. Whenever a WordPress page loads,
internally WordPress checks to see if it needs to fire off wp-cron (by
comparing the current time with the last time wp-cron ran). If it does
need to run wp-cron, then it tries to make an HTTP connection back to
itself, calling the wp-cron.php file.
This connection back to itself is there for a reason. wp-cron has a
lot of work to do, and that work takes time. Delaying the user seeing
his webpage while it does a bunch of stuff is a bad idea, so by making
that connection back to itself, it can run the wp-cron program in a
separate process. Since WordPress itself doesn’t care about the result
of the wp-cron, it only waits a second, then goes back to rendering
the webpage for the user. Meanwhile, wp-cron, having been launched,
does its work until it’s finished or it runs out of execution time.
That HTTP connection is where some badly configured systems fail.
Basically, WordPress is acting like a web browser. If your site was
http://example.com/blog, then WP will call
http://example.com/blog/wp-cron.php to start the process. However,
some servers simply can’t do that for some reason. Among the possible
- Server doesn’t have DNS, and so it can’t figure out who “example.com” is, even though it is itself.
- Server administrators, in a misguided attempt at security, have blocked “loopback” requests, so it can’t actually make a call back to itself.
- Server is running something called “mod_security” or similar, which actively blocks the call due to brain-dead configuration.
- Something else.
The point is that for whatever reason, your web server is configured
in some non-standard way that is preventing WordPress from doing its
job. WordPress simply can’t fix that.
However, if you have this condition, there is a workaround. Add this
to the to defines in your wp-config.php file:define('ALTERNATE_WP_CRON', true);
This alternate method uses a redirection approach, which makes the
users browser get a redirect when the cron needs to run, so that they
come back to the site immediately while cron continues to run in the
connection they just dropped. This method is a bit iffy sometimes,
which is why it’s not the default.
As stated in this great and detailed post, if you have no control over your servers configuration or, if applicable, the environment – a workaround is to put
in your wp-config.php file.