[ GF.dev ] All Tools →

HPKP is Dead — What Replaced It and Why

Published 2026-03-29 · Last modified 2026-03-29

HTTP Public Key Pinning (HPKP) was once considered a cutting-edge security header that let website operators pin their certificate's public key, preventing attackers from using misissued certificates. By 2020, every major browser had removed support. This article explains what HPKP was, why it failed catastrophically in practice, and the modern alternatives that have replaced it.

This article is part of the SSL/TLS Configuration Guide. You can check whether your site still serves legacy HPKP headers with the GF.dev HPKP Test.

What Was HPKP?

HPKP (RFC 7469, published in 2015) allowed a website to send an HTTP response header that instructed browsers to associate the domain with specific cryptographic public keys. On subsequent visits, the browser would reject any certificate whose chain did not include at least one of the pinned keys. The header looked like this:

Public-Key-Pins: pin-sha256="base64+primary==";
    pin-sha256="base64+backup==";
    max-age=5184000;
    includeSubDomains;
    report-uri="https://example.com/hpkp-report"

The idea was compelling: even if a Certificate Authority was compromised or tricked into issuing a fraudulent certificate, the pin would prevent the browser from trusting it.

Why HPKP Failed

HPKP suffered from three fatal problems:

1. Self-Denial-of-Service

If you pinned to the wrong key, lost your private key, or your CA changed intermediates unexpectedly, visitors would be locked out of your site for the entire max-age duration. There was no recovery mechanism short of waiting. A 60-day max-age meant 60 days of downtime for those users. Several high-profile sites experienced this, including Smashing Magazine.

2. RansomPKP Attacks

Security researchers demonstrated that if an attacker gained even temporary control of a site's HTTP responses, they could set malicious HPKP pins with a long max-age, effectively ransoming the domain. The site owner would have no way to undo the pins for any browser that had cached them.

3. Extremely Low Adoption

Due to the risk, only a tiny fraction of sites ever deployed HPKP. Browser vendors concluded that the security benefit for the few sites using it correctly did not justify the risk it posed to the ecosystem.

The Timeline of Removal

What Replaced HPKP?

The goals of HPKP — detecting and preventing misissued certificates — are now addressed by three complementary mechanisms:

1. Certificate Transparency (CT)

Certificate Transparency is a system of public, append-only logs maintained by multiple independent organizations. Every publicly trusted CA is now required to submit certificates to at least two CT logs before issuance. Browsers (Chrome, Safari, Apple) require Signed Certificate Timestamps (SCTs) as proof of CT logging.

This means every certificate issued for your domain is publicly visible. You can monitor CT logs to detect unauthorized issuance. Services like crt.sh, Facebook's CT monitoring, and Google's Transparency Report let you search for certificates by domain.

2. CAA DNS Records

Certificate Authority Authorization (CAA) is a DNS record type that specifies which CAs are allowed to issue certificates for your domain. CAs are required to check CAA records before issuance (since 2017). This prevents most CA misissuance scenarios:

# Only Let's Encrypt can issue for example.com
example.com. IN CAA 0 issue "letsencrypt.org"
example.com. IN CAA 0 issuewild "letsencrypt.org"
example.com. IN CAA 0 iodef "mailto:security@example.com"

The iodef tag specifies where the CA should report policy violations.

3. Expect-CT (Also Now Deprecated)

The Expect-CT header was introduced as a transitional mechanism to let sites opt in to CT enforcement before browsers required it universally. Now that all browsers require CT by default, Expect-CT is no longer needed and was formally deprecated in 2023. You can safely remove it from your headers.

What to Do If You Still Have HPKP Headers

If your site still sends Public-Key-Pins or Public-Key-Pins-Report-Only headers, remove them. They serve no purpose in any modern browser and add unnecessary bytes to every response.

Check with the GF.dev HPKP Test — it will flag any legacy HPKP headers and recommend removal.

# Nginx — remove any lines like:
# add_header Public-Key-Pins '...';

# Apache — remove any lines like:
# Header always set Public-Key-Pins "..."

Modern Certificate Security Checklist

Replace your HPKP deployment with these modern practices:

  1. Set CAA records restricting issuance to your preferred CA(s).
  2. Monitor CT logs for unexpected certificates using crt.sh or a monitoring service.
  3. Enable HSTS with includeSubDomains and preload to prevent downgrade attacks. See What is HSTS?
  4. Use short-lived certificates (90 days via Let's Encrypt) to reduce the window of exposure if a key is compromised.
  5. Remove legacy headers (Public-Key-Pins, Expect-CT).
  6. Test your configuration with the TLS Scanner and Secure Headers Test.

For the full TLS hardening guide, see the SSL/TLS Configuration Guide.

Try These Tools

HPKP Validator