Nginx+Wordpress+Letsencypt result in 403 Forbidden

Hello, I am looking for clues why I can’t resolve 403 error.

My domain on Nginx on Linode VPN. I followed this tutorial and added Letsencrypt certificate to an existing Wordpress site. It continuously shows Forbidden 403 page no matter what settings I change. I’ve installed Certificates twice, last time using this link

I run Letsencrypt client as root, wordpress have 755 and 644 premissions for foiles and folders, owned by www-data, who also is running Nginx. I have multiple wordpress sites on the VPN, have not converted them to HTTP yet and they all are working fine, using the same global/wordpress.conf; and global/restrictions.conf;
I have had previously on one of the non-wordpress sites a StartSSl certificate, which has expiered and I have removed and disabled it, not sure if this can relate since the domains are different…

Also I am getting this error:
2017/04/18 16:54:49 [error] 16929#16929: *1 directory index of “/var/www/html/hosted/” is forbidden, client:, server:, request: “GET / HTTP/2.0”, host: “

I’ve tried swapping directory with a fresh/clean wordpress directory, same result. So, it is not word press fault? But then I can run PHP test from the inside of the site directory ( without problems… So, what is the problem?

hi @localalex

how have you setup your NGINX

do you have a listener for port 443 mapped to your root directory?

If you are not sure best to paste your NGINX config as 403 servers are usually related to server settings not SSL


Hi @ahaw021, here is my Nginx config. I am new to Nginx have not tinkered with it much. Am I missing anything in the config?
indent preformatted text by 4 spaces

    user www-data;
    worker_processes auto;
    pid /run/;
    events {
    worker_connections 768;
            # multi_accept on;
    http {

    # Basic Settings

    client_max_body_size 100m;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    # SSL Settings

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    # Logging Settings

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # Gzip Settings

    gzip on;
    gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;

    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # Virtual Host Configs

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    ## Block spammers and other unwanted visitors  ##
    include blockips.conf;

And here is the website config file:

    server {
        listen 80;
        listen [::]:80;
        return 301 https://$server_name$request_uri;

    root /var/www/html/hosted/;

    index index.php;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    # return 301 https://$server_name$request_uri;

    # Uncoment line below when installing sertificate to Include location directive for Let's Encrypt ACME Challenge
    include global/letsencrypt-acme-challenge.conf;

    # Additional rules go here.
    include global/restrictions.conf;
    include global/wordpress.conf;

     server {
     # SSL configuration

     listen 443 ssl http2;
     listen [::]:443 ssl http2;

    root /var/www/html/hosted/;
    include global/restrictions.conf;
    include global/wordpress.conf;

    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    # from
    # and
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver valid=300s;
    resolver_timeout 5s;

     # Disable preloading HSTS for now.  You can use the commented out header line that includes
     # the "preload" directive if you understand the implications.
     # add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

Also, see netstat output:

tcp        0      0*               LISTEN      3492/mysqld     
tcp        0      0    *               LISTEN      25559/nginx -g daem
tcp        0      0    *               LISTEN      3474/sshd       
tcp        0      0   *               LISTEN      25559/nginx -g daem
tcp        0      0         ESTABLISHED 3492/mysqld     
tcp        0      0      TIME_WAIT   -               
tcp        0      0         ESTABLISHED 3492/mysqld     
tcp        0      0          ESTABLISHED 3549/gogs       
tcp        0      0          ESTABLISHED 3549/gogs       
tcp6       0      0 :::80                   :::*                    LISTEN      25559/nginx -g daem
tcp6       0      0 :::3000                 :::*                    LISTEN      3549/gogs       
tcp6       0      0 :::443                  :::*                    LISTEN      25559/nginx -g daem

hi @localalex

I see you have removed the redirect however if i browses to the redirect is still in effect.

I suggest that you restart the NGINX server and this should give you HTTP (non ssl) connectivity

Then upload a test.html file to your root and try to browse to it over SSL

If that works then the challenges are with WordPress.

I think you may need to update wordpress to server files over HTTPS.



I am unable to get the site load in http, it keeps changing to https, including with www. prefix… I even tried a brand new install of a different browser, with same result. I am beginning to think Wordpress was not meant for providing SSL support…


rather than making silly comments like “Wordpress was not meant for providing SSL support” focus on the problem at hand

there are plenty of SSL Protected Wordpress websites out there

something is redirecting your traffic from HTTP to HTTPS - you need to figure out if it’s NGINX or WordPress and once you have found out what it is reverse the behavior


I agree. I am just frustrated. Will do as you suggested.

Edit: I managed to reverse it back to http and can login into admin. I’ll continue tomorrow with a new attempt to use SSL certificate. Thanks Andrei. I’ll report here how it goes.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.