How To Debug WordPress Upgrade Failing Via FTP Or SSH

Here is a list of reasons why a WordPress internal site or plugin upgrade using FTP, FTPS, or SSH methods might fail.  If your upgrade process is failing (either silently or with an obscure error message), investigate each of these reasons.  If you cannot solve this problem, try to solve the filesystem permissions problem that is causing WordPress to fall back to this method instead of doing a direct upgrade on the filesystem.  Or just force WordPress to use the direct method, if you are sure your filesystem permissions will allow the webserver to do it.


Many plugins can interfere with the upgrade process.  Disable all plugins before beginning the upgrade if you are having problems.

Memory Limits

The upgrade process code downloads a ZIP file containing the plugin to be upgraded, or the entire WordPress distribution in the case of a site upgrade.  The ZIP file is loaded completely into memory while being unpacked.  Therefore, the webserver’s RLimitMEM (or similar) directive must be large enough for the data to fit in the webserver process image.  Additionally, PHP’s max_memory directive must allow for the data to fit.  (You may not be in control of these variables if you are on a shared hosting plan, but it’s worth trying to add them to the .htaccess file to see if it takes effect.)

Web Browser Idle Timeout

Since the WordPress upgrade takes a long time on the server side transferring files via FTP or SSH one by one, the web browser may time out the connection to the web server assuming that something has gone wrong.  The specific setting is dependent on the web browser and the setting can change from version to version.  For example, Firefox versions before 29.0 would not time out a HTTP connection, but later versions introduced such a timeout which must be disabled.

Proxy Server Timeout

If you are running a local proxy server such as Internet Junkbuster or Squid, ensure that the proxy server is not breaking idle connections.  Otherwise, if you are using a consumer ISP such as T-Mobile, the ISP’s transparent web proxy may be the culprit.  If this is the case, the only choice you really have is to tunnel your web client’s HTTP connection through a connection to another TCP port which is not intercepted by the transparent web proxy.

Server-Side Network Problems

If the web server where the WordPress instance is running is a distinct machine from the FTP server that is being used for the upgrade, there may be transient or persistent network issues between the servers themselves.  This will take some effort to diagnose, especially if network address translation (NAT) is involved.  If you have shell access to the web server, you can try using wget to download a number of files from the FTP server and logging the output to examine for failures later.  Improvements to the Wordpress code could work around the clumsy error handling in PHP’s FTP support.

PHP Maximum Script Execution Time

PHP limits the maximum execution time of scripts to avoid denial of service caused by a malfunctioning or malicious script consuming resources indefinitely.  Before each stage of the upgrade, WordPress resets the PHP max_execution_time to 300 seconds to avoid timeouts during that stage.  However, if PHP is configured for a lower timeout to begin with (such as 60), WordPress will not be allowed to increase the value beyond that starting value, and an operation expected to have 300 seconds to execute will only have 60 seconds.  You can try increasing this in .htaccess, but again you may not be allowed to.

PHP FTPS Memory Leak Bug

Most versions of PHP except for those distributed in 2014 and later suffer from a bug which causes SSL FTP connections to leak memory and eventually consume all resources of the server, leading to the server process being killed and the upgrade being aborted.  Here is information on this bug and the fix.  The web server administrator would have to ensure his PHP distribution contains this fix.

Various Errors In Server Log

It is worth checking the server error log to see if there is any output from PHP indicating a problem.  Many key FTP function calls (those starting with ftp_*) in the WordPress FTP filesystem code (class-wp-filesystem-ftpext.php) are silenced by prefixing them with (@), so try removing the @ prefix before any ftp_ calls in order to ensure that output from those functions is logged.  Warning: the output from PHP FTP functions is sometimes misleading, printing only the result of the last operation rather than the reason for the current failure.

Leave a Reply