Short answer
Check the server certificate from the same machine (openssl s_client or curl -v). If it really expired, only the server owner can fix it by renewing. If it is valid, check the system clock, especially in containers and VMs. Then check what the client trusts: an old Node.js version, or a ca option or cafile pointing at an old certificate bundle, can still try a root certificate that has since expired. Upgrade Node.js and remove pinned bundles. Do not turn off verification.
Why the certificate looks expired, and the fix
01
The server certificate really expired
“'CERT_HAS_EXPIRED': Certificate has expired.” Node.js, TLS: X509 certificate error codes
Look at the leaf certificate’s dates first. If the leaf is fine, inspect the rest of the chain (add -showcerts, or use curl -v), because an expired intermediate certificate causes the same error. If notAfter is in the past, the server needs a renewed certificate; for your own domains, check that automatic renewal (for example Let’s Encrypt via certbot or your host) is running.
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -dates02
The machine’s clock is wrong
Validity is checked against local time. A container, VM, CI runner or device with a clock far in the future, or one that lost time after sleep, sees valid certificates as expired. Sync the clock (NTP) and retry.
date -u # compare with the real UTC time03
An old CA bundle or a pinned ca option
“Neither the well known nor extra certificates are used when the ca options property is explicitly specified for a TLS or HTTPS client or server.” Node.js, Command-line options: NODE_EXTRA_CA_CERTS
When a root certificate expires, clients that still use it fail even though the server is fine. Old Node.js versions ship old root lists (and older OpenSSL builds do not try an alternate chain), and code that passes its own ca option, or an npm cafile, uses only that list. Upgrade Node.js, and remove or update pinned bundles.
04
A proxy serving its own certificate
On company networks a proxy may re-sign traffic, and its certificate can expire too. Ask IT for the current proxy root certificate and add it with NODE_EXTRA_CA_CERTS.
Checked against the vendor’s docs on : Node.js: TLS (certificate error codes); Node.js: Command-line options (NODE_EXTRA_CA_CERTS).
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: Node.js ECONNRESET (“socket hang up”) · Axios “Network Error” · JavaScript “TypeError: Failed to fetch” · “self-signed certificate in certificate chain”