Fixing “ERR_TLS_CERT_ALTNAME_INVALID” on a Production NestJS App Hosted on a Shared VPS: Why Your HTTPS 404s’re Ongoing and How to Resolve Them in Minutes
Picture this: you push a fresh NestJS build to your shared VPS, click the HTTPS link, and the browser throws a bright red ERR_TLS_CERT_ALTNAME_INVALID error. You’re left staring at a 404 page, wondering why your hard‑earned SSL certificate is suddenly “invalid.” If you’ve been there, you know the frustration – minutes of debugging turn into hours of lost traffic and revenue.
In this guide we’ll cut through the noise, explain why the error happens on shared VPS environments, and give you a step‑by‑step fix that gets your NestJS API back online in under ten minutes.
Why This Matters
When browsers reject your TLS handshake, every request – API calls, webhooks, even static assets – is blocked. That means:
- Customers can’t reach your service, leading to churn.
- Search engines flag your site as “not secure,” hurting SEO.
- Payments and third‑party integrations throw errors, slowing down revenue.
Fixing the certificate mismatch isn’t just a “nice‑to‑have”; it’s a bottom‑line issue.
Step‑by‑Step Tutorial
-
Confirm the Current Certificate
Run the following OpenSSL command from your local machine (replace
example.comwith your domain):openssl s_client -connect example.com:443 -servername example.comLook for the
Subject Alternative Name(SAN) field. If your domain isn’t listed, the browser will throwERR_TLS_CERT_ALTNAME_INVALID. -
Generate a New CSR with Correct SANs
On your VPS, create a clean
openssl.cnfthat includes every hostname (www, api, subdomains) you serve:[ req ] prompt = no default_bits = 2048 default_md = sha256 distinguished_name = dn req_extensions = req_ext [ dn ] C = US ST = California L = San Francisco O = YourCompany LLC CN = example.com [ req_ext ] subjectAltName = @alt_names [ alt_names ] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = api.example.comThen generate the CSR:
openssl req -new -key private.key -out request.csr -config openssl.cnf -
Obtain a New Certificate (Let’s Encrypt)
If you use Certbot, the command below will automatically pick up the SANs from the CSR:
sudo certbot certonly --manual --preferred-challenges dns \ --csr request.csr \ --agree-tos --email you@yourcompany.comFollow the DNS TXT record instructions; once validated, Certbot saves
fullchain.pemandprivkey.pemin/etc/letsencrypt/live/example.com/. -
Update NestJS HTTPS Options
In your
main.ts(or wherever you bootstrap Nest), point to the new cert files:import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { readFileSync } from 'fs'; import * as https from 'https'; async function bootstrap() { const httpsOptions = { key: readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'), cert: readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem'), }; const app = await NestFactory.create(AppModule, { httpsOptions }); await app.listen(443); } bootstrap(); -
Restart & Verify
Restart your NestJS service (systemd, PM2, etc.) and clear your browser cache. Then run the OpenSSL command again – you should now see your domain listed in the SAN field and no more 404 error.
0 3 * * 0 /usr/bin/certbot renew --quiet && systemctl reload nestjs
Real‑World Use Case
Acme Corp ran an e‑commerce API on a shared VPS with a self‑signed cert. After a DNS change, browsers started rejecting the TLS handshake, and the checkout flow broke for all customers. By following the steps above, they generated a proper SAN‑inclusive Let’s Encrypt cert, updated their NestJS httpsOptions, and restored 100% uptime within 12 minutes. Their conversion rate jumped back up and SEO rankings recovered.
Results / Outcome
- ✅ No more
ERR_TLS_CERT_ALTNAME_INVALIDerrors. - ✅ HTTPS requests hit your NestJS routes instead of a 404.
- ✅ Search engines re‑index your site as “secure,” boosting organic traffic.
- ✅ Automated renewal means you won’t have to repeat this process.
Bonus Tips
- Use a reverse proxy (NGINX) in front of NestJS to offload TLS and simplify certificate management.
- Enable HTTP/2 in your NGINX config for faster API responses.
- Monitor certificate expiry with a free service like SSLShopper to avoid surprise outages.
- Set HSTS headers to force browsers to use HTTPS only:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
privkey.pem file. Keep it permission‑restricted (chmod 600) and stored outside of your project repo.
Monetization (Optional)
If you’re building SaaS tools around NestJS, consider offering a “Certificate Management as a Service” add‑on. Charge a modest monthly fee for automated SSL renewal, monitoring, and support – it’s a recurring revenue stream that solves a pain point for dozens of dev teams.
© 2026 YourTechBlog. All rights reserved.
No comments:
Post a Comment