WordPress shows a Connection Information form asking for an FTP hostname, username and password when you try to install a plugin. Or you get an error like “FTP credentials don’t allow to write to file .htaccess”, or “Unable to write to wp-config.php” during a fresh install.
Both came up on the WordPress.org forums this week, one of them in a thread where it showed up together with Elementor 403 errors and a stuck plugin deactivation. In almost every case the problem is not FTP at all. It is file ownership.
The fix is to make the files owned by the user PHP runs as, then set normal permissions. Typing FTP details into that form, or forcing FS_METHOD, only hides the problem.
Why WordPress suddenly wants FTP
Before WordPress writes plugin, theme or core files, get_filesystem_method() in wp-admin/includes/file.php runs a quick test. It creates a temporary file and compares the owner of that new file with the owner of WordPress’s own files.
If the owners match, WordPress uses direct file access and never asks for anything. If they differ, or the file cannot be created, it falls back to FTP and shows the credentials form.
So the form appears when PHP runs as one user (often www-data, apache or nginx) and the files belong to another, typically the user who uploaded them over FTP or SSH, or root after a restore. The file permissions page in the WordPress docs describes the setup that avoids it: when WordPress can create files with the proper ownership, it “will not ask for FTP credentials when upgrading or installing plugins”.
Step 1. Find the user PHP runs as
Do not guess this one. The web server user and the PHP-FPM pool user are often different. Create a small test file in the WordPress root:
echo '<?php echo get_current_user() . " / " . posix_getpwuid( posix_geteuid() )["name"];' > whoami-test.php
Open https://example.com/whoami-test.php in the browser. The first name is the owner of the file, the second is the user PHP actually runs as. If the two differ, you found your problem.
Delete the test file right away:
rm whoami-test.php
If the page shows a fatal error about posix_getpwuid, the POSIX extension is not loaded. Check the user = line in your PHP-FPM pool config instead, or ask your host.
Step 2. Compare it with the owner of your files
ls -la /var/www/example.com/public_html/
ls -la /var/www/example.com/public_html/wp-content/
The third column is the owner and the fourth the group. Look for mixed results, for example most files owned by www-data but .htaccess or a plugin folder owned by root. Replace the path with your own WordPress root.
Step 3. Back up, then fix ownership
Make a full file backup first. Ownership changes are easy to get wrong on a whole tree.
tar -czf ~/wp-files-backup.tar.gz -C /var/www/example.com public_html
Then set the owner to the PHP user from Step 1. On a VPS where PHP runs as www-data, this is what solved the “Unable to write to wp-config.php” thread, together with the permissions in Step 4:
sudo chown -R www-data:www-data /var/www/example.com/public_html
If PHP runs as your own account user (common on shared hosting and with per-site PHP-FPM pools), use that user and group instead. On shared hosting you usually cannot run chown at all, so ask the host to reset ownership to your account.
💡 If you also deploy over SSH or SFTP as a different user, your next upload brings the problem back. Either deploy as the PHP user or give each site its own PHP-FPM pool that runs as the site user.
Step 4. Set standard permissions
With ownership correct, directories at 755 and files at 644 are enough. Do not use 777. The WordPress docs say no directory should ever get 777, not even uploads.
cd /var/www/example.com/public_html
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
Both find commands are silent when they work. For wp-config.php the docs go stricter and suggest 440 or 400, so other users on the server cannot read it:
chmod 440 wp-config.php
Keep in mind that with 440 nothing can edit wp-config.php from inside WordPress, including plugins that add constants. Switch it to 640 for a moment when you need to edit it, then back.
Step 5. Test and remove workarounds
Go to Tools > Site Health. The notices about files that are not writable and about .htaccess should be gone. Then install and delete a small plugin from Plugins > Add New. It should go through without the FTP form.
If you added define( 'FS_METHOD', 'direct' ); to wp-config.php earlier to make the form go away, remove it now. The docs say direct is chosen automatically when appropriate, and that you should only change this constant if you have update problems. I explain the other values in WordPress FS_METHOD explained.
Doing it from a hosting panel
In OpenPanel there is a Fix Permissions tool in the Files section. You enter a path, or leave it empty to go over everything in /var/www/html/. It sets you as the owner of the website files and folders, sets files to 664 and folders to 775, and fixes FTP account folders so FTP users can still upload. It does not touch emails, databases or file contents. If you prefer 644 and 755, run the two find commands from Step 4 afterwards.
On cPanel servers you cannot change ownership yourself without root, so this usually means a request to the host or a host-specific fix tool.
When ownership is not the cause
If ownership and permissions are correct and WordPress still cannot write, check these before anything else:
- A full disk or inode quota. WordPress cannot create the temp file at all, which looks like a permission error. See Disk Quota Full in WordPress.
- An immutable flag set by a security tool or an admin.
lsattr .htaccessshows aniin the flags if so, andchattr -i .htaccess(as root) removes it. - SELinux on RHEL-based servers. Files restored from a backup can keep the wrong security context, so ask your host or check the audit log.
For .htaccess specifically, also compare the content with the default WordPress rules in WordPress .htaccess file examples, because a 403 can also come from a bad rule rather than from permissions.
TL;DR: the FTP credentials form means the PHP user does not own your WordPress files. Find the PHP user, chown the WordPress root to it, set 755 for directories and 644 for files, and remove any FS_METHOD workaround. Check ownership again after every restore or manual upload.

