ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN means your browser has a cached HPKP (HTTP Public Key Pinning) record for this domain, and the certificate currently being served does not contain a public key that matches any of the pinned hashes. The site is blocked until the cached pin expires or you clear the browser’s security state for that domain.
HPKP was deprecated by Chrome in Chrome 67 (May 2018) and removed from all major browsers. If you are encountering this error in 2026, either: (a) your browser cached an HPKP header years ago and the pin has not yet expired, (b) you are running an old browser version, or (c) the site is still serving a Public-Key-Pins header and you are hitting it fresh. The fix depends on which scenario applies.
What HPKP Was and Why It Caused This Error
HTTP Public Key Pinning (HPKP) was an HTTP header that allowed a website to tell browsers: ‘only trust this site if the certificate chain contains a public key whose SHA-256 hash matches one of these values.’ The mechanism was designed to prevent man-in-the-middle attacks using fraudulently issued certificates from other CAs.
A typical HPKP header looked like this:
Public-Key-Pins: pin-sha256=”base64==”; pin-sha256=”backupBase64==”; max-age=5184000; includeSubDomains
The header required at least two pins: one for the current certificate’s public key and one backup (in case the current key was compromised and needed replacement). The max-age value was in seconds. The browser stored this pin record and enforced it on every subsequent visit for max-age seconds.
The fatal design flaw: if the certificate was renewed with a new key pair (different public key), the stored pin no longer matched the new certificate. The browser blocked the site completely, with no override option. There was no recovery path except waiting for max-age to expire. Sites that set max-age to a year or two and then rotated their keys became permanently inaccessible to any browser that had cached the old pin.
HPKP is not the same as HSTS. HTTP Strict Transport Security (HSTS) tells browsers to only use HTTPS and is still active, recommended, and important for security. HPKP pinned specific certificate public keys and is deprecated. Do not remove HSTS headers while trying to fix this error.
The Four Scenarios and How to Fix Each One
Scenario A: Your site is still serving a Public-Key-Pins header
This is the scenario where you control the server and can fix it at the source. Verify by running:
curl -I https://yourdomain.com | grep -i public-key-pins
If the header appears in the output, your server is still sending HPKP. The fix:
- Remove the Public-Key-Pins header from your web server configuration. In Nginx: remove the add_header Public-Key-Pins line and reload. In Apache: remove the Header always set Public-Key-Pins directive and restart.
- After removing the header, browsers that visit the site will stop receiving new pins. However, browsers that already have the old pin cached will continue enforcing it until their cached pin expires (max-age seconds from when they last received the header).
- If the cached pin is blocking users right now: deploy a Public-Key-Pins header that contains a pin matching the current certificate’s public key. This overwrites the cached pin with one that matches. Once all users have received the corrected header, remove the HPKP header entirely.
To calculate the correct pin for your current certificate:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
The output of that command is the pin-sha256 value for your current certificate’s public key. If you are generating a backup pin from a different key, run the same command against the backup key file: openssl pkey -in backup-key.pem -pubout -outform der | openssl dgst -sha256 -binary | base64
Scenario B: Your site no longer serves HPKP but a user’s browser has the old pin cached
This scenario has no server-side fix. The browser will enforce the cached pin until max-age seconds have elapsed from the last time the browser received the HPKP header. You cannot push an update to clear cached pins in other users’ browsers.
Options:
- Wait it out: if the max-age was set to a reasonable value (30 days = 2,592,000 seconds), affected users recover automatically. If max-age was set to a year or longer, this is not practical.
- Instruct affected users: see Scenario D below for instructions you can give to users whose browsers are blocked.
- Serve matching certificate: if you still have the private key that corresponds to the pinned public key hash, install that certificate on the server. The browser will accept it. Then gradually phase out the old key by setting a new HPKP header with updated pins before removing HPKP entirely.
Scenario C: You are a developer and it is your own browser
This is the easiest fix. Chrome provides a direct mechanism to clear HSTS and HPKP records for specific domains:
- In Chrome, navigate to: chrome://net-internals/#hsts
- Scroll to the ‘Delete domain security policies’ section at the bottom.
- Enter the domain name (without https:// and without path) in the text field.
- Click Delete.
- Navigate to chrome://net-internals/#sockets and click ‘Flush socket pools’ to clear any cached connections.
- Reload the page.
If that does not work, clear all browsing data for the specific site:
- In Chrome, click the padlock/tune icon in the address bar while on the affected domain.
- Select Site settings.
- Click Clear data.
- Retry the page.
The chrome://net-internals/#hsts tool works for both HSTS and HPKP records. If you are a developer working on a site during migration and encountering this error repeatedly, clear the record each time you change the certificate configuration rather than waiting for max-age to expire.
Scenario D: A user is reporting this error on your site
Provide the user with these instructions:
- Open Chrome Settings (three dots menu, then Settings).
- Go to Privacy and security, then Clear browsing data.
- Select Advanced tab.
- Check ‘Cached images and files’ and ‘Cookies and other site data.’
- Change time range to ‘All time.’
- Click Clear data.
- Close and reopen Chrome, then retry the site.
Alternatively, provide the chrome://net-internals/#hsts instructions from Scenario C if the user is technically comfortable.
Why This Error Appears in 2026 Despite HPKP Being Deprecated
HPKP was deprecated by Chrome in Chrome 67 (May 2018). However, three scenarios produce the error years after deprecation:
- Long max-age values: some developers set max-age to 5,184,000 seconds (60 days), 31,536,000 seconds (1 year), or longer. A browser that cached an HPKP header in 2017 with a 2-year max-age would enforce it until 2019. Long max-age values can still be in effect years after the header was removed from the server.
- Old browser versions: browsers older than Chrome 67 still enforce HPKP. Enterprise environments with locked browser versions, Chromium-based embedded browsers, or users who have not updated in years may still enforce HPKP headers they cached before the deprecation.
- Sites still serving HPKP: some server configurations have not been updated since HPKP deprecation. Servers running old web application frameworks or containerized applications deployed from 2015-2018 images may still include HPKP headers. The curl command from Scenario A confirms whether this is happening.
The RSA-to-ECDSA migration is a specific trigger for this error in 2026. Many developers who implemented HPKP pinned RSA-2048 key hashes. If they subsequently upgraded their certificate to ECDSA P-256 (for performance reasons, or following a hosting provider’s default certificate change), the public key changed entirely (different algorithm, different hash), invalidating any cached RSA key pin. The error appears even though the new ECDSA certificate is valid and issued by a trusted CA.
Certificate Pinning in Mobile Applications: A Different Problem
The ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN error is specific to browser HPKP. Certificate pinning in mobile applications (iOS, Android) is a separate implementation that produces different error behavior. If users are reporting connection failures in a mobile application rather than in a browser, the issue is application-level certificate pinning, not HPKP.
Application-level certificate pinning requires updating the application itself when certificates are renewed with new keys. This is a development and release management problem, not a server configuration problem. The fix requires releasing an application update with the new certificate hash before the old certificate expires.
Prevention: What to Do Instead of HPKP
HPKP has been replaced by Certificate Transparency-based controls and the Expect-CT header (itself now deprecated in favor of CT being mandatory for all certificates since 2018). For modern certificate security:
- Rely on Certificate Transparency: all publicly trusted certificates are logged in CT logs. Monitor CT logs for your domain using tools like crt.sh, Facebook’s Certificate Transparency Monitoring, or Cloudflare Radar. You will be notified of any unauthorized certificate issuance without the HPKP risk.
- Use CAA DNS records: CAA records tell CAs which CAs are authorized to issue certificates for your domain, preventing unauthorized issuance at the source. See the CAA Record entry in the SSL Certificate Glossary.
- Enable HSTS (not HPKP): HSTS tells browsers to only use HTTPS. Use HSTS with a 1-year max-age and includeSubDomains. Submit to the HSTS preload list at hstspreload.org for the strongest HSTS protection. HSTS does not have the catastrophic misconfiguration risk of HPKP.
Frequently Asked Questions
The error says NET::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN. Is this the same error?
Yes. NET::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN and ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN are the same error with slightly different formatting depending on Chrome version. Both indicate an HPKP pin mismatch. Apply the same fixes.
Does this error occur with HTTPS certificate pinning in Nginx or Apache configuration?
No. Nginx and Apache SSL configuration does not implement HPKP. This error is caused only by the Public-Key-Pins HTTP header that a site served previously. Check for HPKP headers with the curl command in Scenario A. If no HPKP header is present on the server, the issue is a cached pin in the browser and the fix is browser-side (Scenarios B through D).
My site never used HPKP. Why am I seeing this error?
If your site has never served a Public-Key-Pins header, you should not see this error from your domain. Verify by running the curl command from Scenario A. If no HPKP header appears and the error still occurs, check whether a CDN, load balancer, or proxy in front of your server has a cached or residual HPKP header configuration. AWS CloudFront, Cloudflare, and similar services can serve custom headers; confirm that none of them are injecting a Public-Key-Pins header that your origin server does not serve directly.
