Certificate is installed but suddenly stopped working

Hello all. Been using an SSL cert granted by certbot for quite a while now. However, I now find it is rejected by browsers as an invalid "self signed" cert.

Bypassing warning gives nginx 401 refusal page.

I have not changed anything and rerunning certbot does not fix the issue.

Can anyone help me figure out what broke?

My domain is: winged-horse.fyi

I ran this command:

It produced this output:

My web server is (include version): nginx/1.28.0

The operating system my web server runs on is (include version): arch

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): certbot 5.0.0

Something in your web server configuration would be the obvious guess. Your domain doesn't seem to be accessible from the public Internet, so it's pretty hard to say anything further.

2 Likes

my domain works absolutely fine from the public internet, it has more going on than https. like plain http access for the same site (i serve only static html and do not strictly need security except for browsers who won't load traditional http sources) and a number of other non web hosted services.

I just ran nginx -t and got this wonderful delight:

2025/11/16 23:00:56 [emerg] 2410#2410: cannot load certificate "/etc/letsencrypt/live/winged-horse.fyi/fullchain.pem": BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(/etc/letsencrypt/live/winged-horse.fyi/fullchain.pem, r) error:10080002:BIO routines::system lib)
nginx: configuration file /etc/nginx/nginx.conf test failed

I'd have to disagree:

But the error you've posted indicates the cert is missing or unreadable, so that would be the thing to check.

2 Likes

In the most polite way possible: That screenshot is of a website that just tries to connect to HTTPS.

I have my phone here with wifi turned off, and using mobile data, I can connect to winged-horse.fyi over ssh and through plain http.

my URL is perfectly open to the world.

keyfile also exists:

lrwxrwxrwx 1 root root 45 Nov 16 22:52 /etc/letsencrypt/live/winged-horse.fyi/fullchain.pem -> ../../archive/winged-horse.fyi/fullchain2.pem

In the most polite way possible: connections via http return a permanent redirect to HTTPS. which fails.

The file you list is the cert file, not the key file. And it also doesn't show that the target of that symlink exists. Can you check that?

3 Likes

That is a choice the client makes, not my server. If you care to go directly to plain http instead of redirecting, you will see it works.

or even just use ping.

Which shows nothing about the status of your website.

But you obviously know what's going on, so you don't need me. Carry on.

2 Likes

You said

Your domain doesn't seem to be accessible from the public Internet,

And then posted a screenshot which you believed proved that it isn't.

Ping would show that the domain is, in fact, accessible from the public internet.

You are right though in that I most certainly don't need help from someone who unwittingly demonstrates they don't know how to check a URL exists or not, and then digs himself into a hole over it. Checking if a URL exists is the easy part of the problem.

Please post your nginx config for review or pass it through an nginx configuration linter.

1 Like

Sure thing, the conf file is pretty long so I've put it in a pastebin to keep the thread clutter free:

Here's the full output of nginx -t

2025/11/17 00:01:02 [warn] 3480#3480: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
2025/11/17 00:01:02 [warn] 3480#3480: could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size
2025/11/17 00:01:02 [emerg] 3480#3480: cannot load certificate "/etc/letsencrypt/live/winged-horse.fyi/fullchain.pem": BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(/etc/letsencrypt/live/winged-horse.fyi/fullchain.pem, r) error:10080002:BIO routines::system lib)
nginx: configuration file /etc/nginx/nginx.conf test failed

What are your thoughts on this error? Does the file existing and is nginx able to read it?

1 Like
lrwxrwxrwx 1 root root 45 Nov 16 22:52 /etc/letsencrypt/live/winged-horse.fyi/fullchain.pem -> ../../archive/winged-horse.fyi/fullchain2.pem

checking the symlink, fullchain2.pem exists:

-rw-r--r-- 1 root root 1294 Oct  7 11:06 cert1.pem
-rw-r--r-- 1 root root 1294 Nov 16 22:52 cert2.pem
-rw-r--r-- 1 root root 1566 Oct  7 11:06 chain1.pem
-rw-r--r-- 1 root root 1566 Nov 16 22:52 chain2.pem
-rw-r--r-- 1 root root 2860 Oct  7 11:06 fullchain1.pem
-rw-r--r-- 1 root root 2860 Nov 16 22:52 fullchain2.pem
-rw------- 1 root root  241 Oct  7 11:06 privkey1.pem
-rw------- 1 root root  241 Nov 16 22:52 privkey2.pem

Me and presumably others are getting a timeout error when trying to connect to https.

You're on certbot 5.0.0. The 5.1.0 release notes say this:

Fixed a bug in certbot-nginx that'd leave nginx configured with self-signed
certificates if a user ran certbot enhance and they didn't have matching
SSL server blocks. certbot enhance now requires the user to have a matching
SSL server block to enable HSTS or OCSP stapling enhancements.

So that could be the cause of your issue. And upgrading might fix it going forward. (Although I'm not sure how you'd get out of this broken state. May have to force a renewal or search on the filesystem for the correct cert/key and move it over manually)

The error in nginx -t could just be because the command is running as a user that's not authorised to acces the file. (The NGINX service probably can access it, although it'd be good to verify this. I'd not expect nginx to start/reload successfully if it weren't able to.)

2 Likes

updating certbot to 5.1.0 and forcing (another) cert renewal has had no effect.

Your nginx config has two HTTP server blocks. One has a listen 80; directive the other has no such directive but the default nginx behaviour is:

If the directive is not present then either *:80 is used if nginx runs with the superuser privileges, or *:8000 otherwise.

So you might have two server blocks configured to use port 80. That's probably not the cause of your issue, but it'd be good to fix this.

What does sudo nginx -t say?

Can you share the certificate that nginx returns? I can't access the site over https but seeing the cert might help narrow down where the issue is coming from.

2 Likes

sudo nginx -t:

2025/11/17 00:49:13 [warn] 1408#1408: could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size
2025/11/17 00:49:13 [warn] 1408#1408: conflicting server name "winged-horse.fyi" on 0.0.0.0:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

I'm signing out for today, but I think the certificate you're seeing in your browser and the certbot logs would be helpful info for people here.

1 Like

[root@Swiftwind letsencrypt]# cat letsencrypt.log
2025-11-17 00:39:23,131:DEBUG:certbot._internal.main:certbot version: 5.1.0
2025-11-17 00:39:23,132:DEBUG:certbot._internal.main:Location of certbot entry point: /usr/bin/certbot
2025-11-17 00:39:23,132:DEBUG:certbot._internal.main:Arguments: []
2025-11-17 00:39:23,132:DEBUG:certbot._internal.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#nginx,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
2025-11-17 00:39:23,140:DEBUG:certbot._internal.log:Root logging level set at 30
2025-11-17 00:39:23,145:INFO:certbot.ocsp:Cannot extract OCSP URI from /etc/letsencrypt/live/winged-horse.fyi/cert.pem
2025-11-17 00:39:23,146:DEBUG:certbot._internal.display.obj:Notifying user: Found the following certs:
  Certificate Name: winged-horse.fyi
    Serial Number: 6bb5d5f2e68f1580c145719086101a8155f
    Key Type: ECDSA
    Domains: winged-horse.fyi
    Expiry Date: 2026-02-14 23:39:03+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/winged-horse.fyi/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/winged-horse.fyi/privkey.pem

Can nginx also read the private key? I assume nginx isn't running as root.