How to Fix 'Installation failed: Destination folder already exists' in WordPress

intermediate📝 WordPress2026-04-24| WordPress 5.5+, Linux/Unix Servers (Ubuntu, CentOS, Debian), Nginx/Apache

Error Message

Installation failed: Destination folder already exists
#wordpress#plugin#theme#sftp#wp-cli

Why Your WordPress Update Just Hit a Wall

I ran into a common but annoying roadblock today while updating a client's custom theme. I uploaded the new .zip file, expecting a quick success message, but WordPress stopped me cold with this:

Installation failed: Destination folder already exists

This error usually signals a failed update or a manual upload gone wrong. If a large plugin like WooCommerce or Elementor times out—often hitting the default 30-second PHP max_execution_time limit—it leaves behind a half-extracted folder. WordPress sees that directory, gets nervous about overwriting data, and simply quits.

Identifying the "Ghost" Folder

When this happens, WordPress is being protective. It sees a folder with the same name as your new upload and refuses to touch it. My first move was to check the wp-content/plugins/ directory. Even though the plugin wasn't active in the dashboard, the folder was physically there. That "ghost" folder is your culprit.

Solution 1: Manual Cleanup via SFTP (The Surefire Way)

Manual deletion is my preferred method because it's surgical. If you have SFTP access via FileZilla or WinSCP, follow these steps to clear the path:

  • Connect to your server and head to /public_html/wp-content/plugins/ (or /themes/).
  • Find the folder named after the plugin you’re trying to install.
  • Pro tip: Download a quick backup of the folder to your desktop before hitting delete.
  • Delete the folder from the server.

Using the command line? It's even faster. Just be careful with the rm command:

# Move to the plugins directory
cd /var/www/html/wp-content/plugins/

# Confirm the folder name
ls -d */

# Wipe the offending folder (replace 'plugin-slug' with the actual folder name)
rm -rf plugin-slug/

With the debris cleared, head back to your dashboard and retry the upload. It should work perfectly.

Solution 2: Forcing the Install with WP-CLI

If you prefer the terminal, WP-CLI is a lifesaver. You can bypass the manual deletion entirely by using the --force flag. This tells WordPress to ignore existing files and overwrite them with the contents of your ZIP file.

# For a plugin
wp plugin install /path/to/plugin.zip --force

# For a theme
wp theme install /path/to/theme.zip --force

This is the most efficient route for developers managing multiple environments.

Solution 3: Using the "Replace Current" Dashboard Feature

Since version 5.5, WordPress has included a built-in safety valve. Usually, if you upload a ZIP that already exists, a screen appears asking if you want to "Replace current with uploaded." It even shows you the version numbers to compare.

However, this feature relies on a valid style.css or plugin header being present. If the previous installation failed mid-extraction, that metadata might be missing. If you don't see the "Replace" button, you must use the SFTP method in Solution 1.

Dealing with Permissions (The 403 Error)

Sometimes you’ll try to delete the folder only to see a "Permission Denied" error. This happens when the web server user (like www-data or nginx) owns the files, but your SFTP user doesn't. You can fix this by resetting ownership:

# Reset ownership to the web user
sudo chown -R www-data:www-data /var/www/html/wp-content/plugins/plugin-name

# Or set permissions to 755
sudo chmod -R 755 /var/www/html/wp-content/plugins/plugin-name

Double-Checking the Fix

Once the install finishes, verify your work. Check the Plugins page to ensure the version number is correct and activate it. I also recommend checking your site's front-end immediately. A quick glance at the file system via ls -l can confirm the new folder has the current timestamp, proving the overwrite was successful.

Prevention: Don't Get Stuck Again

Keep your environment clean. Most of these hiccups are caused by server timeouts during automatic updates. If you frequently see this, consider increasing your memory_limit to 256M and your max_execution_time to 300 in your php.ini. Using WP-CLI for large updates is also a great way to avoid browser-based connection drops.

Related Error Notes