How to Set Up SSL Correctly with Nginx and Let’s Encrypt in 2026

How to Set Up SSL Correctly with Nginx and Let’s Encrypt in 2026

June 16, 2026

General illustration of HTTPS lock, Nginx, and certificate automation

Getting SSL/TLS right on an Nginx site is no longer just a “nice-to-have.” In 2026, browsers, APIs, search engines, and user expectations all assume HTTPS by default. A correct setup protects credentials and session cookies, reduces the risk of tampering, improves trust, and helps avoid browser warnings that can destroy conversions before a visitor even sees your content. Let’s Encrypt remains a widely used free, automated CA, and its ACME ecosystem continues to evolve, including shorter certificate lifetimes and ARI-based renewal coordination. (letsencrypt.org)

This guide walks through a practical, modern Nginx + Let’s Encrypt setup for 2026. It focuses on getting the basics right first, then tightening TLS, automation, and hardening so your deployment stays reliable even as certificate policies change. Let’s Encrypt’s own documentation emphasizes automation and up-to-date ACME clients, while Nginx’s current HTTPS guidance reflects modern defaults such as TLS 1.2 and 1.3. (letsencrypt.org)

1. Why SSL/TLS matters for Nginx sites in 2026: security, trust, and HTTPS adoption

SSL, more accurately called TLS today, does three important jobs for your Nginx site: it encrypts traffic, verifies the server’s identity, and protects data in transit from tampering. Without TLS, anyone on the network path can observe or modify requests and responses. That matters for login pages, checkout flows, admin panels, API endpoints, and even plain content pages that use cookies or personalization. In a world where most browsers visibly flag insecure sites, encryption is also about trust: visitors are more likely to stay when they see a secure connection. (letsencrypt.org)

By 2026, HTTPS is effectively the baseline for credible web publishing. Search engines, modern browsers, and many third-party services assume secure transport. Let’s Encrypt also notes that its certificates are standard DV certificates for any server using a domain name, and that automation is the intended operating model. That makes TLS less of a “special project” and more of an operational requirement. (certbot.eff.org)

There is another 2026-specific reason to care: certificate lifetimes are getting shorter. Let’s Encrypt has announced a staged transition from 90-day certificates to 64-day and then 45-day certificates, with renewal around day 30 for 45-day certs. That means manual renewals and ad hoc setups are increasingly fragile. If your TLS setup is not automated and tested, it will eventually fail at the worst possible time. (letsencrypt.org)

2. Prerequisites and planning: domain DNS, server access, firewall ports, and Nginx version

Before installing anything, verify the basics. First, your domain’s DNS must point to the server where Nginx is running. Let’s Encrypt must be able to validate control of the domain, usually through the HTTP-01 challenge on port 80 or through DNS-01 if you need wildcard certificates. Let’s Encrypt’s challenge documentation states that HTTP-01 places a token at http://YOUR_DOMAIN/.well-known/acme-challenge/TOKEN and requires port 80. (cp.letsencrypt.org)

Second, make sure you have shell access to the server, usually over SSH, and root or sudo privileges. Certbot’s Nginx plugin generally needs elevated access to change Nginx configuration and reload the service. Certbot’s own installation guidance assumes you can run it on the command line of the web server. (certbot.eff.org)

Third, open firewall ports 80 and 443. Port 80 is needed for issuance and renewal when using HTTP-01, and 443 is needed for the secure site itself. Let’s Encrypt explicitly notes that HTTP-01 only uses port 80, while redirects are allowed only to HTTP or HTTPS on ports 80 or 443. (cp.letsencrypt.org)

Fourth, check your Nginx version. This matters because modern Nginx uses a newer http2 directive approach, and older syntax like listen ... http2 is now deprecated in upstream development notes. Also, Nginx’s HTTPS docs state that the default TLS protocol set is TLS 1.2 and TLS 1.3, which is exactly what you want in a modern deployment. (mailman.nginx.org)

3. Install Certbot and the Nginx plugin: choosing the right ACME client workflow

For most Nginx sites, Certbot remains the simplest ACME client workflow because it can request certificates and update Nginx automatically. Certbot’s ecosystem documents the --nginx path as a standard option for websites already online on the server. If your server is Linux-based and you can run commands as root, this is usually the fastest path from “plain HTTP” to “valid HTTPS.” (certbot.eff.org)

There are three common workflows to think about:

  1. Nginx plugin: Certbot edits Nginx config for you, performs validation, and can often add HTTPS redirect rules.

  2. Webroot method: Certbot places challenge files in an existing document root, while you manage the config yourself.

  3. DNS-01 method: Best for wildcards or when port 80 is not reachable, but it requires DNS API access or manual TXT record updates. (cp.letsencrypt.org)

If you operate a standard public website, the Nginx plugin is often the right default. If you want more control or your Nginx config is custom, webroot is usually the safer manual option. If you need wildcard certificates, Certbot says you need a DNS plugin or a script that can update DNS records, because that is how DNS-01 works for unattended renewals. (certbot.eff.org)

A good rule in 2026: choose the workflow that is easiest to automate reliably. Shorter certificate lifetimes make “remembering to run a command later” a bad strategy. Up-to-date ACME clients are more important than ever, especially with Let’s Encrypt’s newer renewal and profile changes. (letsencrypt.org)

4. Issue your first Let’s Encrypt certificate: Nginx plugin vs webroot method

If your Nginx site is already serving a domain on port 80, the Nginx plugin is the fastest way to get started. Certbot can validate domain control, issue the certificate, and often rewrite your server block to use the new certificate files. The benefit is convenience: fewer manual steps, fewer opportunities to misplace paths, and less chance of forgetting a reload. (certbot.eff.org)

The webroot method is better when you want to keep full control of your Nginx configuration. In this method, Certbot places the ACME challenge file into a directory that Nginx already serves. Let’s Encrypt then fetches the challenge token from /.well-known/acme-challenge/ over HTTP. This method is especially useful when you already have a carefully tuned config and do not want a plugin to modify it. (cp.letsencrypt.org)

A typical issuance flow looks like this:

sudo certbot --nginx -d example.com -d www.example.com

Or, with webroot:

sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com

The exact flags may vary by package manager and Certbot version, but the idea is the same: validate ownership, issue the cert, then point Nginx at the resulting fullchain.pem and privkey.pem. Certbot’s documentation also recommends testing with --dry-run during renewal checks, which is especially important before you trust automation in production. (eff-certbot.readthedocs.io)

5. Configure Nginx for strong TLS: HTTP/2, TLS 1.2/1.3, modern ciphers, and safe defaults

Once the certificate exists, the real work begins: configuring Nginx to use strong defaults. Modern Nginx guidance centers on TLS 1.2 and TLS 1.3, which are the protocols you should allow unless you have a very unusual legacy requirement. Nginx’s HTTPS documentation also reflects the newer http2 directive model, and upstream notes state that the old listen ... http2 style is deprecated. (nginx.org)

A clean server block often looks like this:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    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;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    # Keep cipher configuration minimal for modern TLS.
    # TLS 1.3 ciphers are not controlled the same way as TLS 1.2.
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    root /var/www/example;
    index index.html;
}

The exact cipher string is less important than the principle: avoid old protocols, avoid obsolete cipher suites, and prefer modern defaults unless you have a compatibility reason to do otherwise. Nginx’s current docs support the notion that the server can be configured safely without legacy TLS 1.0/1.1. (nginx.org)

If you reverse proxy to an upstream app, preserve host and client context. Nginx’s proxy documentation shows proxy_set_header Host $host; and related forwarding headers as the standard pattern. That helps your app generate correct URLs and recognize that the original request was secure. (nginx.org)

6. Force HTTPS correctly: redirect HTTP to HTTPS and preserve host and path

A proper HTTPS migration includes a clean redirect from port 80 to port 443. The redirect should preserve the hostname and path so http://example.com/a/b?x=1 becomes https://example.com/a/b?x=1. That way users, bookmarks, and search crawlers land where they expect. Let’s Encrypt’s HTTP-01 docs also make it clear that redirects are followed, but only within allowed schemes and ports. (cp.letsencrypt.org)

A simple redirect server block is enough:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

This pattern is usually better than hardcoding a single hostname, because $host preserves the requested hostname and $request_uri preserves path and query string. That matters when you serve multiple names or when one canonical host redirects to another. (nginx.org)

Be careful not to create loops. A common mistake is redirecting traffic to HTTPS in the proxy app and again in Nginx, or using a load balancer that already terminates TLS while Nginx believes every request is HTTP. If your app sits behind another proxy, make sure the upstream receives the correct forwarded headers so it knows the original scheme. Nginx’s proxy docs and examples show the standard Host and forwarding header approach. (nginx.org)

7. Enable automatic renewal: systemd timers, cron jobs, and renewal testing

Automation is not optional anymore. Let’s Encrypt certificates are designed for renewal, and current policy changes make reliable renewal even more important. Let’s Encrypt’s rate limits documentation notes that the preferred renewal detection method is ARI, which is exempt from all rate limits, while older renewal logic may still face some limits. (letsencrypt.org)

Most modern installs use either a systemd timer or a cron job to run certbot renew. The exact mechanism depends on how Certbot was installed, but the objective is the same: periodically check whether any certificate is due and renew it before expiration. After renewal, Nginx should be reloaded so it starts serving the updated certificate. Certbot’s documentation explicitly supports --dry-run, which you should use to validate the whole pipeline before relying on it in production. (eff-certbot.readthedocs.io)

A common testing pattern is:

sudo certbot renew --dry-run

Then confirm that Nginx reloads cleanly and your site still serves the new chain. If you manage multiple certificates, check them regularly and review renewal logs. Shorter lifetimes in 2026 mean that a configuration that “usually works” is no longer good enough. Let’s Encrypt’s 2026 timeline states that the default lifetime will move from 90 days to 64 and then 45, so an automation failure will show up much faster than in the past. (letsencrypt.org)

8. Harden the setup: OCSP stapling, HSTS, secure headers, and key file permissions

After the basics are working, harden the deployment. OCSP stapling can reduce client lookups to the CA and improve privacy by letting your server present a cached revocation response during the TLS handshake. Let’s Encrypt has discussed OCSP stapling as a way to reduce load and preserve privacy, although community guidance also notes that Nginx staples from cache and behavior can vary if no response is already cached. (letsencrypt.org)

A practical Nginx stapling configuration usually includes:

ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

That said, do not assume stapling will be perfect in every circumstance. Nginx’s behavior depends on cached OCSP data, resolver availability, and certificate chain details. In other words, it is a useful hardening measure, but not something you should treat as magic. (community.letsencrypt.org)

HSTS is another valuable layer. It tells browsers to always use HTTPS for your domain for a specified time. A common starting point is a modest max-age, then later a longer one once you are confident everything is stable. Use caution with includeSubDomains and especially with preload, because mistakes can lock in bad behavior for a long time. Nginx’s header mechanics require careful placement of add_header so the directive applies where you expect it to. (trac.nginx.org)

Finally, protect the private key. The key file should be readable only by root or the process that genuinely needs it. If your Nginx worker does not need direct access, keep the default restrictive permissions and avoid copying keys around unnecessarily. That is basic hygiene, but it matters more when certificates renew automatically and files are touched repeatedly. (certbot.eff.org)

9. Troubleshooting common SSL problems: redirect loops, mixed content, chain issues, and port conflicts

The most common HTTPS issues are usually configuration mistakes, not cryptography problems. Redirect loops happen when the application, Nginx, or a load balancer all try to force HTTPS independently. To fix that, decide which layer owns the redirect and ensure upstream services understand the original scheme through forwarded headers. Nginx’s proxy documentation shows the standard header forwarding pattern, including Host and X-Forwarded-For. (nginx.org)

Mixed content is another common problem. This happens when the page loads over HTTPS, but scripts, images, fonts, or API calls still use http://. Browsers may block those requests or warn users. The fix is to update application templates, asset URLs, and any hardcoded backend endpoints so everything uses relative URLs or HTTPS. This is not a Let’s Encrypt issue; it is a deployment hygiene issue. (letsencrypt.org)

Chain issues often show up when Nginx uses the wrong certificate file. In most Let’s Encrypt setups, you should point ssl_certificate to fullchain.pem, not just the leaf certificate, so browsers receive the full chain they need. If users see “incomplete chain” warnings, confirm the file path and re-run a test with your browser or openssl s_client. Certbot’s standard output paths are designed for this workflow. (certbot.eff.org)

Port conflicts are also common. If another service is already bound to 80 or 443, Certbot and Nginx may fail to validate or restart cleanly. Check for competing processes, container port mappings, or a reverse proxy in front of Nginx. Since HTTP-01 validation depends on port 80, blocking that port will break issuance unless you switch to DNS-01. (cp.letsencrypt.org)

10. Future-proofing your deployment: shorter certificate lifetimes, ARI, and staying current with Let’s Encrypt changes

Future-proofing in 2026 means assuming certificate policy will keep changing. Let’s Encrypt has already announced a staged move from 90-day certificates to 64-day and then 45-day certificates, with a corresponding change in expected renewal timing. That means your operational margin is shrinking, and your renewal workflow needs to be truly hands-off. (letsencrypt.org)

The big feature to watch is ARI, or ACME Renewal Information. Let’s Encrypt says ARI is the preferred renewal method and is exempt from rate limits. In practice, that means modern ACME clients can ask the CA for a recommended renewal window rather than relying only on a fixed “renew X days before expiry” rule. Let’s Encrypt’s 2025 and 2026 ARI posts and rate-limits documentation make it clear that this is the direction of travel. (letsencrypt.org)

Timeline of certificate lifetime changes and automated renewal readiness

Short-lived certificates are also part of the picture. Let’s Encrypt made six-day certificates generally available in 2026, and the organization has said that short-lived certificates are opt-in for now. Even if you do not use them, their existence is a signal: the industry is moving toward more frequent automation and shorter trust windows. (letsencrypt.org)

The best defense is simple: keep Certbot current, keep Nginx current, test renewal regularly, and monitor Let’s Encrypt’s announcements. When certificate lifetimes shrink again, mature automation will make the transition routine instead of painful. (letsencrypt.org)

Conclusion

A correct Nginx + Let’s Encrypt setup in 2026 is about much more than “turning on HTTPS.” It is a combination of proper validation, modern TLS settings, clean redirects, dependable automation, and hardening that fits how browsers and certificate authorities work today. If you get the basics right, the rest becomes easier to maintain. (nginx.org)

The key takeaways are straightforward: use a modern ACME client, automate renewal, serve the full certificate chain, redirect HTTP to HTTPS correctly, and keep your configuration aligned with current Nginx and Let’s Encrypt guidance. Most importantly, prepare for shorter certificate lifetimes and ARI-based renewals now, before those changes become mandatory for your workflow. (letsencrypt.org)

References