WordPress on Amazon EC2: Permission Denied Error Message

This is part of my Introduction to Hosting WordPress on Amazon Web Services (AWS) tutorial.

  • Are you new to hosting WordPress with an Amazon Web Services (AWS) EC2 instance using the WordPress Certified by Bitnami and Automattic Amazon Machine Image (AMI)?
  • Are you having problems accessing the files in your WordPress installation via FTP?
  • Do you see a Permission denied error message when you try to upload, edit, or delete a file from your WordPress Installation using FTP?

Read these instructions for a quick (and dirty) fix to this problem. After that, if you want, you can read on for an explanation.


Update: May 2020

This article was originally created in June 2018 and completely updated in May 2020. I will not be updating it going forward.

If you found this article, you probably are having the issue described here. However, I have noticed that Bitnami has made changes to its WordPress deployment for AWS, so if you are using a newer version of the he WordPress Certified by Bitnami and Automattic AMI, you may not encounter this issue. It looks like Bitnami has changed the default ownership properties for the directories and files that make up the WordPress installation.

In 2018 when I first encountered this issue and created this article to describe the problem and a solution, I was using the Bitnami AMI that was running Ubuntu 16.04.4 LTS with Bitnami WordPress 4.9.8-3. When I used ls -al to list the ownership for the WordPress installation, the owner and group were both daemon.

However, when I rewrote this article in May 2020, I was using a newer version of the Bitnami AMI that used Ubuntu 16.04.6 LTS with Bitnami WordPress 5.4-0. When you list the ownership permissions here, the owner is bitnami but the group is daemon, suggesting that the bitnami user has elevated privileges and the ability to create, update, and delete the files and folders within the WordPress installation.

These troubleshooting steps assume that you have already familiarized yourself with the steps in WordPress on Amazon EC2: Connect to an Instance via SSH and WordPress on Amazon EC2: Connect to an Instance via FTP. I am using Terminal and Cyberduck on a Mac, but the commands I use in Terminal and the steps I take in Cyberduck are very basic.

Symptom: Permission Denied error messages

I have established an SFTP connection to my WordPress installation, which is a WordPress Certified by Bitnami Amazon Machine Image (AMI) from Amazon Web Services (AWS). When I try to use the Cyberduck client to upload, edit, or delete files on my WordPress installation, I see the following error message:
Permission denied. Please contact your web hosting service provider for assistance.

  • Upload failed/Permission denied error message when trying to upload a file from the WordPress installation via SFTP:
    Upload <filename> failed.
    Permission denied. Please contact your web hosting service provider for assistance.
  • Download failed/Permission denied error message when trying to edit or download a file from the WordPress installation via SFTP:
    Download <filename> failed.
    Permission denied. Please contact your web hosting service provider for assistance.
  • Cannot delete/Permission denied error message when trying to delete a file from the WordPress installation via SFTP:
    Cannot delete <filename>.
    Permission denied. Please contact your web hosting service provider for assistance.

Without an ability to create, update, or delete the files in my WordPress installation, I will be very limited in my abilities to customize my WordPress site. To remedy this, I need to use the chown command to change the ownership of the entire WordPress installation.

Solution: chown Your WordPress Installation

  1. Use Terminal to connect to your EC2 instance by following the steps in WordPress on Amazon EC2: Connect to an Instance via SSH.
  2. Use cd to navigate to the directory to the WordPress installation:
    cd /opt/bitnami/apps/wordpress/htdocs/
  3. Use the stat command to see the user and group that own this directory:
    stat -c %U /opt/bitnami/apps/wordpress/htdocs/
  4. The command line responded that the owner of the directory is daemon, which basically means you do not control it. For our purposes, we need to change the owner to bitnami, which is the name of the user we are using to connect to the EC2 instance, both via SSH and via SFTP.
    sudo chown -R bitnami:bitnami /opt/bitnami/apps/wordpress/htdocs/
  5. Now that we have changed the ownership, use Cyberduck to connect to your instance and navigate to the WordPress installation by following the steps in WordPress on Amazon EC2: Connect to an Instance via FTP. When you get there, find wp-config.php, click on it once, and then click the pencil icon for Edit at the top of the Cyberduck browser window.
  6. If you changed the ownership to bitnami correctly, the wp-config.php file will open in your text editor. For the purposes of demonstration, I will add a change to the file as a comment and save it.
  7. You can confirm that the file has been saved by checking the Modified date in the Cyberduck browser window.
  8. Next we are going to make sure we can upload files to the WordPress installation. Let’s navigate to the current month in the uploads folder. Twirl the arrows down so that you navigate to htdocs/wp-content/uploads/2018/06.
  9. Drag and drop a file from your computer into the 2018/06 directory. In my case I used a file named l-i_2019_007.png. Cyberduck’s Transfers window should show you the progress of the upload and display Upload complete when it’s done.
  10. OK, so now we’ve uploaded a file. Let’s delete the file we just uploaded to test if we can also delete files. Click on the same file to select it.
  11. Right-click or control-click on the file and select Delete from the menu.
  12. A pop-up will ask you to confirm that you want to delete the file. Click Delete.
  13. The file is gone. We now know that we can create, update, and delete files in the WordPress installation using our FTP client.
  14. Click the Disconnect button in the top-right corner of the Cyberduck browser window.
  15. It is very important that when you are done updating the files in your WordPress installation that you change the ownership back to daemon. Go back to Terminal and enter:
    sudo chown -R daemon:daemon /opt/bitnami/apps/wordpress/htdocs/
  16. Let’s use the stat command to confirm that we chown’d the directory back to daemon:
    stat -c %U /opt/bitnami/apps/wordpress/htdocs/
  17. OK, the owner is daemon. We’re done here. Type exit and press Enter to terminate the SSH connection.

For People Who Care: What Just Happened Here?

Before trying to host WordPress on Amazon Web Services (AWS) EC2 instances, I had used HostGator, StableHost, and GoDaddy. With each of these hosting services, you can use cPanel to easily create FTP accounts, and then use an FTP client to connect to your hosting provider and, more specifically, your WordPress installation.

Having FTP access to your WordPress installation is critical for many WordPress functions, including customizing your own themes and child themes, or even just updating the wp-config.php file, perhaps the most important single file in your entire WordPress installation.

But as soon as I started using AWS, everything changed. The SFTP connection protocol was new for me, and I didn’t really know what the private keys and PEM files were. Once I actually succeeded in connecting to the EC2 instance with Cyberduck I had to poke around and find where the WordPress Certified by Bitnami and AUtomattic AMI places the WordPress location. I found it, navigated into wp-content, tried to upload something, and got Permission denied.

I played around some more and found that I could download files, and if it was something like a JPEG, I could open it, but essentially I was stuck with read-only privileges: no way to create, update or delete anything in my WordPress installation.

I kept poking around, going back up the way I came to see if I could figure it out. With WordPress Certified by Bitnami and Automattic, the file path to the WordPress installation is /opt/bitnami/apps/wordpress/htdocs.

  1. I was read-only in htdocs, where WordPress is.
  2. I went up a level and found I also could not upload to or delete files from wordpress.
  3. Same with apps.
  4. Once I got to bitnami, I could upload an image and then delete it.

I was seriously stuck. I asked the guy who had introduced me to AWS and, when he tried to replicate the problem, he did. I did a lot of Googling and did not find an answer right away. I started to wonder if AWS was going to work out for me. Eventually I found posts on the Bitnami Community and learned that what I need to use was the chown command.

chown is a command used on Unix- and Linux-based systems. It stands for change ownership. I’m only here to talk about a very specific use of this command, so I am only going to talk about this:

sudo chown -R daemon:daemon /opt/bitnami/apps/wordpress/htdocs/
  • sudo: Super-user do, a command which, if you have access to it, gives you admin-level privileges.
  • chown: Change ownership.
  • -R: Recursively apply this chown command to the specified directory and all of the other files and directories contained within it.
  • daemon:daemon: The user and group (user:group) that have ownership permissions; in this case both the user and the group are daemon, which is kind of like the system acting for itself, as opposed to being controlled by you
  • /opt/bitnami/apps/wordpress/htdocs/: Again, this is the complete file path to the location of the WordPress installation.

To be a little more thorough, I want to check who own the thing before I change anything, so I use this command:
stat -c %U /opt/bitnami/apps/wordpress/htdocs/

The response is daemon. daemon owns the file, and it is daemon who is stopping me from changing or deleting files in the WordPress installation. I’ve been researching how this specific EC2 instance works enough to know that my username is bitnami: it’s the username for my FTP connection and it appears on the command line when I connect to the instance. So use the chown command to change the ownership of the WordPress installation to bitnami:
sudo chown -R bitnami:bitnami /opt/bitnami/apps/wordpress/htdocs/

After this you will find that you can put files in the WordPress installation, delete them, or update your PHP, CSS, and other types of files using a code editor.

Listen: This is the most important part of what we are doing here today. You need to change the ownership back to daemon. Not only would not doing so immediately leave your site vulnerable, it will also effectively breaks most of the functionality of your WordPress site. If you don’t believe me, try updating your wp-config.php file with the ownership set to bitnami and see what happens.

It’s the same command, but with daemon:daemon as the user and group:
sudo chown -R daemon:daemon /opt/bitnami/apps/wordpress/htdocs/

Type exit to disconnect. You can also disconnect on Cyberduck.

You’re done. When I created this I was not a prolific Terminal user, so I saved snippets of the commands used in this process (specific to my own EC2 instance) in a text file so that I can do all of this a lot quicker. Here are the three commands that you will really need:

sudo chown -R bitnami:bitnami /opt/bitnami/apps/wordpress/htdocs/
sudo chown -R daemon:daemon /opt/bitnami/apps/wordpress/htdocs/
stat -c %U /opt/bitnami/apps/wordpress/htdocs/

Again, do not forget: when you are finished, chown it back to daemon:daemon.