Skip to main content

Let's Encrypt Is Out of Beta: Free HTTPS for Everyone, and a New Way to Fail

Let's Encrypt has left beta after issuing over a million free certificates. How ACME works, a basic nginx setup, and the silent renewal failure to watch for.

The CompleteStatus Team 5 min read

Let's Encrypt Is Out of Beta: Free HTTPS for Everyone, and a New Way to Fail

Want this checked continuously?

CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.

Monitor your site free

On April 12, Let's Encrypt dropped the "beta" label. In the four months since its public beta opened in December, the free certificate authority has issued well over a million certificates, and a meaningful share went to sites that had never had HTTPS at all. The project's stated goal is a 100% encrypted web, and for the first time that looks achievable.

If you've been waiting for Let's Encrypt to be "ready" before trusting it with your sites, this is that milestone. Here's what it is, how to set it up, why its 90-day certificates are a deliberate choice, and the new failure mode it introduces.

What Let's Encrypt actually is

Let's Encrypt is a certificate authority run by the non-profit Internet Security Research Group, with backing from Mozilla, the EFF, Akamai, Cisco and others. Three things make it different from the CAs before it:

  • Free. Domain-validated certificates cost nothing. The $50–$200/year toll on encryption is gone.
  • Automated. Certificates are issued and renewed by software speaking an open protocol called ACME. Your server proves it controls the domain (typically by serving a challenge file) and the CA issues the certificate. No web forms, no approval emails.
  • Short-lived. Certificates are valid for 90 days, not the one to three years the industry is used to. More on why below.

The official client is also changing hands: the letsencrypt tool is moving to the EFF and is due to be renamed Certbot. The commands below use the current letsencrypt name; once the rename ships, swap in certbot.

Setting it up with nginx

The webroot method is the least invasive way to start. It doesn't touch your server config; it drops challenge files where your existing site can serve them. First, make sure nginx serves the challenge path:

server {
    listen 80;
    server_name example.com www.example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
    }
}

Then request the certificate:

letsencrypt certonly --webroot -w /var/www/letsencrypt \
    -d example.com -d www.example.com

The client proves domain control, and your certificate and key land in /etc/letsencrypt/live/example.com/. Point nginx at them:

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}

Reload nginx and you're serving HTTPS with a certificate every major browser trusts. Renewal is one command: letsencrypt renew checks all your certificates and renews any within 30 days of expiry. The standard approach is a cron job:

0 3 * * * letsencrypt renew --quiet && systemctl reload nginx

Total cost: nothing, and about fifteen minutes. If you've been putting off the HTTPS migration (we made the case in February), the last practical excuse is gone.

Why 90 days is a feature

The short lifetime is the most complained-about design decision, and also the most deliberate one:

  • Shorter lifetimes limit damage. A compromised or mis-issued certificate is dangerous for as long as it's valid, and revocation on the web is famously unreliable. Ninety days caps that exposure at three months instead of three years.
  • They force automation. Nobody wants to renew by hand every few months, so 90-day certificates push you to automate, and automated renewal is more reliable than a calendar reminder. The one-year certificate you installed by hand is the one everyone forgets until the browser warning appears.
  • Automation scales. Once renewal is a cron job, adding HTTPS to the next site, or the next fifty, is trivial.

Manual certificate management is where expiry outages come from. Let's Encrypt is forcing the fix.

The new failure mode: silent renewal breakage

With traditional certificates, the failure mode was forgetting: a renewal date passes unnoticed. With automated 90-day certificates it's subtler. The automation itself breaks, and nothing tells you.

The causes are all mundane:

  • The cron job was never installed on the new server after a migration. The certificate works fine for up to 90 days, then expires.
  • The webroot moved. A deploy restructured directories, the ACME challenge now 404s, and every renewal attempt fails.
  • A firewall or nginx change blocked port 80, which the challenge needs.
  • The certificate was renewed but nginx was never reloaded, so it keeps serving the old one from memory.
  • Rate limits or a client error stall renewals, and the error goes to a cron mailbox nobody reads.

Every one of these is invisible for weeks. The certificate stays valid right up until it doesn't, and then every visitor gets a full-page browser security warning, which is downtime in every way that matters.

So don't let the system that renews the certificate be the only system that knows when it expires. Renewal should be verified from the outside, by something independent of the server, the cron daemon and the ACME client.

Verifying it from outside

CompleteStatus connects to your site the way a browser does, inspects the certificate actually being served (not the one on disk) and tracks its expiry date. If renewal breaks for any of the reasons above, the served certificate's remaining lifetime keeps shrinking past the point where it should have been renewed, and you get an alert weeks before expiry. It also catches the case where renewal succeeded but the web server was never reloaded.

Create a free account and add SSL monitoring to your newly encrypted sites.

Written with AI assistance and reviewed by the CompleteStatus team.