Try this when Let's Encrypt's Certbot fails a challenge with Nginx

2022-01-24

This happened to me today while setting up SSL on Moon Monster. The website was up and running on Nginx. But when I went to generate certificates with Let's Encrypt's Certbot with sudo certbot --nginx -d themoon.monster -d www.themoon.monster I got the following error:

... Performing the following challenges: http-01 challenge for themoon.monster http-01 challenge for www.themoon.monster Waiting for verification... Challenge failed for domain themoon.monster Challenge failed for domain www.themoon.monster ... Some challenges have failed. ...

It also went on to say that it received 404 Not Found responses from my server. This was puzzling because my website was being served just fine. I did some Googling, and user234683 on Stack Overflow had my solution. I needed to add the following lines to my Nginx configuration:

Listen 80; Listen [::]:80;

After I got it working, I was still puzzled. Why was my website working just fine with out those two lines, yet not having them broke Certbot? That brought me to the Nginx docs for the listen directive. "If the directive is not present then either *:80 is used if nginx runs with superuser privileges, or *:8000 otherwise." So by default Nginx does not listen to IPv6 addresses, but Cerbot sends challenges using IPv6 if there is an AAAA for your domain. By adding those two lines, specifically the second one, Nginx began accepting requests to my IPv6 address and was able to respond to the Certbot challenges.

Boulder, the application that is behind Let's Encrypt and Certbot, will fall back to IPv4, but only if it fails to make any connection on IPv6 and there is no redirect on IPv4. Since Boulder was able to connect to my server, albeit just to receive a 404, it did not reattempt on IPv4.