Nginx Certbot Challenge failing with 404

Im running into a weird error with certbot and nginx that i have no idea what is causing it, so simply running the command:

sudo certbot --nginx -d domain.com

results in this:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for domain.com

Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
  Domain: domain.com
  Type:   unauthorized
  Detail: X.X.X.X: Invalid response from http://domain.com/.well-known/acme-challenge/Ib8K0pxsfmdHNnOwgbkynpeZ5wMzFdaxF4swDjp95DQ: 404

Hint: The Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the internet.

Some challenges have failed.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.

My first thought is i have some miss configuration on nginx, btw this is the config certbot is using from the logs:

2025-11-21 13:49:48,276:DEBUG:certbot_nginx._internal.parser:Writing nginx conf tree to /etc/nginx/sites-enabled/domain.com:
server {rewrite ^(/.well-known/acme-challenge/.*) $1 break; # managed by Certbot

 


    listen 80;

    server_name domain.com;

    location ~ {
	return 404;
    }



location = /.well-known/acme-challenge/Ib8K0pxsfmdHNnOwgbkynpeZ5wMzFdaxF4swDjp95DQ{default_type text/plain;return 200 Ib8K0pxsfmdHNnOwgbkynpeZ5wMzFdaxF4swDjp95DQ.4_COb_XMFHYCDpTA3K5_ik_c602Htth32k3WHGjDx20;} # managed by Certbot

}

After lots of testing using the same configuration and simplifying it all i kept getting the same error, to make this even weirder while certbot was running and showing the 404 error i clicked on the link pointing to the challenge path and it loaded the link on my browser without any error this is while the tool was running, and ofc after the tool exited the link stopped working showing that the configuration was indeed loaded correctly. i m not really sure what i should test or what the problem is any pointers would be greately appreciated.
Few points, i cant use weebroot instead of --nginx since i have a whole setup already running and dont want to have to update it since it legacy code, the system was working and just stopped randomly not changes have been made to the code or config files (i did do a system upgrade to ubunto 22), this is not happening to a single domain either.

Certbot version:

certbot 5.1.0

Nginx version:

nginx version: nginx/1.18.0 (Ubuntu)

Request log:

2025-11-21 13:49:53,524:DEBUG:urllib3.connectionpool:https://acme-v02.api.letsencrypt.org:443 "POST /acme/authz/1014845267/616276716986 HTTP/1.1" 200 1024
2025-11-21 13:49:53,524:DEBUG:acme.client:Received response:
HTTP 200
Server: nginx
Date: Fri, 21 Nov 2025 13:49:53 GMT
Content-Type: application/json
Content-Length: 1024
Connection: keep-alive
Boulder-Requester: 1014845267
Cache-Control: public, max-age=0, no-cache
Link: <https://acme-v02.api.letsencrypt.org/directory>;rel="index"
Replay-Nonce: -l2dNf_XGlFTfIpKVLlGx3CuCo0SGz66ggB7LltOxPRnO0VNGIA
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800

{
  "identifier": {
    "type": "dns",
    "value": "domain.com"
  },
  "status": "invalid",
  "expires": "2025-11-28T13:49:44Z",
  "challenges": [
    {
      "type": "http-01",
      "url": "https://acme-v02.api.letsencrypt.org/acme/chall/1014845267/616276716986/2C5l8w",
      "status": "invalid",
      "validated": "2025-11-21T13:49:52Z",
      "error": {
        "type": "urn:ietf:params:acme:error:unauthorized",
        "detail": "X.X.X.X: Invalid response from http://domain.com/.well-known/acme-challenge/Ib8K0pxsfmdHNnOwgbkynpeZ5wMzFdaxF4swDjp95DQ: 404",
        "status": 403
      },
      "token": "Ib8K0pxsfmdHNnOwgbkynpeZ5wMzFdaxF4swDjp95DQ",
      "validationRecord": [
        {
          "url": "http://domain.com/.well-known/acme-challenge/Ib8K0pxsfmdHNnOwgbkynpeZ5wMzFdaxF4swDjp95DQ",
          "hostname": "domain.com",
          "port": "80",
          "addressesResolved": [
            "X.X.X.X"
          ],
          "addressUsed": "X.X.X.X"
        }
      ]
    }
  ]
}

Does this nginx system have a large number of server blocks? If so you might need to add --nginx-sleep-seconds X to your command. The default for X is 1 but you may need 3 or more. The reason is that after Certbot adds that temp code to your nginx server it does an async nginx reload and waits 1 second before requesting the cert. If nginx hasn't reloaded in that 1s it won't have the needed location and return and, in your case, will reply with a 404 to the incoming request from Let's Encrypt's server.

If not that, did you do the test request from your local network or the public internet?

Because a '404' (HTTP Not Found) error when using the --nginx option is unusual. One possibility is the public DNS uses the wrong IP or multiple IP. Another good option is there are multiple nginx systems and the wrong one is responding. This can happen with a routing problem (like NAT or port forwarding) or even a firewall appliance that runs nginx seeing the request first.

If none of that applies we'll need to know more about the system you are running and the actual domain name.

Webroot doesn't normally require any changes to your nginx config. Although, the optimal way uses location blocks for /.well-known/acme-challenge path and / path (to redirect to HTTPS). We can give specific example if you go this route.

If you do need --nginx-sleep-seconds you should definitely consider switching to --webroot method. Certbot's --nginx option is not well suited for large installations.

2 Likes

You're a life saver thank you so much this is exactly the issue, i have hundreds of server blocks that explains why it just stopped working randomly, i would've never even known this options exists, thank you so much.

3 Likes