Back to Troubleshooting

Fix WordPress FTP Prompt via PHP-FPM Pool | NOC.org Support

When WordPress asks for FTP or SFTP credentials to install plugins, update themes, or perform core updates, it means the PHP process cannot write to the WordPress files directly. This is almost always a file ownership mismatch between the PHP-FPM pool user and the owner of the WordPress files on disk. This guide explains the root cause and how to fix it properly.

Why WordPress Asks for FTP Credentials

Before writing to the filesystem (installing a plugin, updating a theme, etc.), WordPress calls get_filesystem_method() to determine how it should write files. This function creates a temporary file in the WordPress directory and checks if the owner of that temp file matches the owner of the WordPress files.

  • If the owners match, WordPress uses the direct method — it writes files directly using PHP's file functions.
  • If the owners do not match, WordPress assumes it does not have proper permissions and falls back to requesting FTP/SFTP credentials to write files as a different user.

The temp file is created by PHP, so its owner is whatever user PHP-FPM is running as. If PHP-FPM runs as www-data but the WordPress files are owned by ubuntu (or any other user), the owners will not match and you will see the FTP prompt.

Understanding PHP-FPM Pool Configuration

PHP-FPM (FastCGI Process Manager) runs PHP as separate worker processes. Each "pool" defines a set of worker processes with specific settings, including the system user and group they run as. Pool configurations are stored in:

# Default pool file:
/etc/php/8.2/fpm/pool.d/www.conf

# Or for other PHP versions:
/etc/php/7.4/fpm/pool.d/www.conf
/etc/php/8.0/fpm/pool.d/www.conf
/etc/php/8.1/fpm/pool.d/www.conf

Key Settings in the Pool Config

[www]
; The user and group PHP-FPM workers run as:
user = www-data
group = www-data

; The socket or port to listen on:
listen = /run/php/php8.2-fpm.sock

; Socket ownership:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

The Fix: Match PHP-FPM User to File Owner

You have two options: change the PHP-FPM pool user to match the file owner, or change the file ownership to match the PHP-FPM user.

Option 1: Change the PHP-FPM Pool User (Recommended for Multi-site Servers)

If your WordPress files are owned by a specific user (e.g., wpuser), create a custom pool that runs as that user:

# Create a custom pool file:
sudo nano /etc/php/8.2/fpm/pool.d/wordpress.conf
[wordpress]
user = wpuser
group = wpuser

listen = /run/php/php8.2-fpm-wordpress.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5

php_admin_value[open_basedir] = /var/www/wordpress/:/tmp/
php_admin_value[disable_functions] = exec,passthru,shell_exec,system

Then update your Nginx or Apache configuration to use the new socket:

# Nginx:
fastcgi_pass unix:/run/php/php8.2-fpm-wordpress.sock;

# Apache (with mod_proxy_fcgi):
SetHandler "proxy:unix:/run/php/php8.2-fpm-wordpress.sock|fcgi://localhost"

Option 2: Change File Ownership to Match PHP-FPM User

If PHP-FPM runs as www-data, change the WordPress file ownership:

# Change ownership of all WordPress files:
sudo chown -R www-data:www-data /var/www/wordpress/

# Set correct directory permissions:
sudo find /var/www/wordpress/ -type d -exec chmod 755 {} \;

# Set correct file permissions:
sudo find /var/www/wordpress/ -type f -exec chmod 644 {} \;

This is simpler but means all WordPress files are owned by the web server user, which has security implications on shared hosting.

Setting Correct Directory and File Permissions

Regardless of which approach you use, the permissions should be:

Path Permissions Notes
Directories 755 (rwxr-xr-x) Owner can read/write/execute; others can read/execute
Files 644 (rw-r--r--) Owner can read/write; others can read
wp-config.php 640 (rw-r-----) Restrict access to owner and group only
wp-content/uploads/ 755 Must be writable by PHP-FPM user

Alternative: Define FS_METHOD in wp-config.php

You can force WordPress to use the direct filesystem method by adding this to wp-config.php:

define('FS_METHOD', 'direct');

This tells WordPress to skip the ownership check and always write files directly. However, this only works if PHP actually has write permissions to the files. If the permissions are wrong, you will get "Could not create directory" errors instead of the FTP prompt.

Important: Using FS_METHOD direct is a workaround, not a fix. The proper solution is to ensure the PHP-FPM user matches the file owner so that the ownership check passes naturally.

Verifying Your PHP-FPM Configuration

# Check which user PHP-FPM is running as:
ps aux | grep php-fpm

# Example output:
# root      1234  ...  php-fpm: master process
# www-data  1235  ...  php-fpm: pool www
# wpuser    1236  ...  php-fpm: pool wordpress

# Check the file ownership:
ls -la /var/www/wordpress/wp-config.php
# -rw-r----- 1 wpuser wpuser 3456 Jan 15 10:30 wp-config.php

# Verify PHP-FPM pool user matches file owner:
# Pool "wordpress" runs as "wpuser" ✓
# Files owned by "wpuser" ✓
# = WordPress will use direct filesystem method

Restarting PHP-FPM After Changes

# Restart PHP-FPM:
sudo systemctl restart php8.2-fpm

# Check for configuration errors:
sudo php-fpm8.2 -t

# Verify the service is running:
sudo systemctl status php8.2-fpm

Common Mistakes

  • Forgetting to restart PHP-FPM after editing pool configuration. Pool settings are only loaded on start/restart.
  • Setting permissions to 777. Never do this. It makes all files writable by any user on the system, creating a serious security vulnerability.
  • Mixing chown and FS_METHOD. If you set FS_METHOD to direct but the PHP-FPM user cannot write to the files, updates will fail with filesystem errors.
  • Forgetting listen.owner. The socket must be readable by the web server (Nginx/Apache). If Nginx runs as www-data, set listen.owner = www-data.

For a full guide on setting up Nginx with PHP-FPM, see Nginx, PHP, and SSL on Ubuntu. For broader server hardening, see the Linux security checklist.

Improve Your Websites Speed and Security

14 days free trial. No credit card required.