I’m not sure why, but my custom Wordpress 404 page will not load with an improper URL that should 404, instead, the default Nginx 404 page loads. All pages are working as expected, I just want a 404 to be my 404, not the default. I’ve tried changing my permalinks just to update them, no luck. I suspect it has to do with my sever block, any ideas?

server {
        # The below listen is moved / contained in a server block down below, controlled by CertBot.
        # Only ONE default_server is allowed.
        # listen 80 default_server;
        # listen [::]:80 default_server;

        root /var/www/porterbytes.com/html;
        index index.php index.html index.htm index.nginx-debian.html;

        server_name porterbytes.com www.porterbytes.com;

        location / {
            #try_files $uri $uri/ =404;
            try_files $uri $uri/ /index.php?$args =404;
        }

        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }

        location ~ /\.ht {
            deny all;
        }

        location = /favicon.ico { log_not_found off; access_log off; }
        location = /robots.txt { log_not_found off; access_log off; allow all; }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
            expires 7d;
            add_header Cache-Control "public, no-transform";
            log_not_found off;
        }


    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/porterbytes.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/porterbytes.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = www.porterbytes.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = porterbytes.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80 default_server;
        listen [::]:80 default_server;

        server_name porterbytes.com www.porterbytes.com;
    return 404; # managed by Certbot




}

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

×
1 answer

Hi there @Porter,

I think that the problem is caused by this line in your config here:

        location / {
            #try_files $uri $uri/ =404;
            try_files $uri $uri/ /index.php?$args =404;
        }

The =404 pice at the end tells nginx to handle the 404 pages rather than letting your WordPress handle that.

Try removing that the =404 part, run a config test with:

nginx -t

If you get Syntax ok restart Nginx and try again.

Let me know how it goes!
Regards,
Bobby

  • I tried removing that bit, no errors, restarted nginx with sudo service nginx restart. Still got the same 404 page :(

    The only other mention of a 404 is from Cerbot, down below.

    It’s worth noting that my Wordpress install is contained at /wordpress (with the site being served at the main domain). This appeared to be causing some issues with gutenburg (I couldn’t create pages, or update them), despite the home page displaying just fine. Maybe this 404 bit is related to that as well, not sure.

    server {
        if ($host = www.porterbytes.com) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
    
        if ($host = porterbytes.com) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
    
            listen 80 default_server;
            listen [::]:80 default_server;
    
            server_name porterbytes.com www.porterbytes.com;
        return 404; # managed by Certbot
    
    
    
    
    }
    
    • Hi there @Porter,

      The Certbot part should be ok as you are being redirected to https before you get to the return 404 part.

      I’ve actually created a new Droplet to test this, I used the exact same config as you currently do but removed the =404 part as mentioned in my previous comment and it worked as expected, I was able to see the WordPress 404 page rather than the Nginx one.

      Do you have any caching plugins installed which could have cached the 404 page?

      Regards,
      Bobby

      • @bobbyiliev Other than my site-specific plugin (configs custom post types, cleans up admin area, etc), there’s nothing at all, completely vanilla install, using the Genesis Framework (custom theme build from the child Sample Theme).

        Just so it’s all out in the open, I did set up SSL (as you saw), http2, and ipv6. I’m not aware of how those would interfere, but I wanted to make it known. Due to Wordpress being in its own directory, I did have to alter my server block slightly to be able to create / update any posts (would love clarification on this if possible, but we can stay on subject if desired).

        I just updated it again, restarted nginx, and rebooted. I did notice that I got an error once I rebooted, I had to kill apache2 in order to restart nginx again, or view my site, so I probably need to delete something there. I think I read that PHP7.4 (I recently updated) installs Apache stuff with it, so I’m assuming I have a loose end there. That said, with the changes, restarted, everything up and running, I still don’t get the 404. On the Wordpress side, I refreshed my permalinks, just to be sure. I’m pretty sure the file simply needs to be in my theme folder, and be named 404.php, yeah? Just want to rule out that’s not my error, as this is certainly a deeper dive than a minor Wordpress template error haha

        My current server block looks like this now (restarted nginx, and rebooted server, killed apache2 as required).

        https://porterbytes.com/

        server {
                # The below listen is contained in a server block down below, controlled by CertBot.
                # Only ONE default_server is allowed.
        
                root /var/www/porterbytes.com/html;
                index index.php index.html index.htm index.nginx-debian.html;
        
                server_name porterbytes.com www.porterbytes.com;
        
                location / {
                    rewrite_log on; rewrite ^(.*?)$ /wordpress$1;
                }
        
                location /wordpress/ { 
                    rewrite ^/wordpress/wp-json/(.*?)$ /wordpress/index.php?rest_route=/$1 last; 
                }
        
                location /wordpress {
                    try_files $uri $uri/ /wordpress/index.php?$args;
                }
        
                location ~ \.php$ {
                    include snippets/fastcgi-php.conf;
                    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
                }
        
                location ~ /\.ht {
                    deny all;
                }
        
                location = /favicon.ico { log_not_found off; access_log off; }
                location = /robots.txt { log_not_found off; access_log off; allow all; }
                location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                    expires 7d;
                    add_header Cache-Control "public, no-transform";
                    log_not_found off;
                }
        
        
            listen [::]:443 ssl ipv6only=on; # managed by Certbot
            listen 443 ssl; # managed by Certbot
            ssl_certificate /etc/letsencrypt/live/porterbytes.com/fullchain.pem; # managed by Certbot
            ssl_certificate_key /etc/letsencrypt/live/porterbytes.com/privkey.pem; # managed by Certbot
            include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
        
        
        }
        server {
            if ($host = www.porterbytes.com) {
                return 301 https://$host$request_uri;
            } # managed by Certbot
        
        
            if ($host = porterbytes.com) {
                return 301 https://$host$request_uri;
            } # managed by Certbot
        
        
                listen 80 default_server;
                listen [::]:80 default_server;
        
                server_name porterbytes.com www.porterbytes.com;
            return 404; # managed by Certbot
        
        
        
        
        }
        
        
        • @bobbyiliev I just wanted to update you, that I used another domain and set up a fresh install of Wordpress on the same server, and everything works as expected. I’ve also discovered that https://porterbytes.com/wordpress/ displays my 404 page!, but no other URL will 404, just that one.

          As much as I’d love to solve this, I’m not seeing any particularly clear benefits to having Wordpress in its own directory, and I’m seeing a hell of a lot of headaches. At this point, I think it just makes sense to migrate the site to be within /html/, rather than in a subdirectory. The only reason I really did it, was for organization purposes, but it adds nothing.

          If you happen to have an answer before I go ahead, I’d be happy to implement it and report back, otherwise, time to drop this nonsense and get back to work!

          • Hi there @Porter,

            Ah yes indeed, I would probably go for moving the site to the document root rather than overriding this with a rewrite rule.

            And in case that you need to host multiple websites on the same Droplet, I would recommend just using separate server blocks.

            Regards,
            Bobby

            by Justin Ellingwood
            When using the Nginx web server, server blocks (similar to the virtual hosts in Apache) can be used to encapsulate configuration details and host more than one domain off of a single server. In this guide, we'll discuss how to configure server blocks in Nginx on an Ubuntu...
Submit an Answer