ory/hydra · error
unable to load X509 key pair: %v
Error message
unable to load X509 key pair: %v
What it means
After both base64 decodes succeed, CertificateFromBase64 calls tls.X509KeyPair to parse the PEM cert and key. This error means the bytes are valid base64 but do not form a valid X.509 key pair: bad PEM blocks, mismatched cert/key, unsupported key format, or expired/malformed certificate.
Source
Thrown at oryx/tlsx/cert.go:84
- ` + prefix + `_KEY: Base64 encoded (without padding) string of the private key (PEM encoded) to be used for HTTP over TLS (HTTPS).
Example: ` + prefix + `_KEY="-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDg..."
`
}
// CertificateFromBase64 loads a TLS certificate from a base64-encoded string of
// the PEM representations of the cert and key.
func CertificateFromBase64(certBase64, keyBase64 string) (tls.Certificate, error) {
certPEM, err := base64.StdEncoding.DecodeString(certBase64)
if err != nil {
return tls.Certificate{}, fmt.Errorf("unable to base64 decode the TLS certificate: %v", err)
}
keyPEM, err := base64.StdEncoding.DecodeString(keyBase64)
if err != nil {
return tls.Certificate{}, fmt.Errorf("unable to base64 decode the TLS private key: %v", err)
}
cert, err := tls.X509KeyPair(certPEM, keyPEM)
if err != nil {
return tls.Certificate{}, fmt.Errorf("unable to load X509 key pair: %v", err)
}
return cert, nil
}
// [deprecated] Certificate returns a TLS Certificate by looking at its
// arguments. If both certPEMBase64 and keyPEMBase64 are not empty and contain
// base64-encoded PEM representations of a cert and key, respectively, that key
// pair is returned. Otherwise, if certPath and keyPath point to PEM files, the
// key pair is loaded from those. Returns ErrNoCertificatesConfigured if all
// arguments are empty, and ErrInvalidCertificateConfiguration if the arguments
// are inconsistent.
//
// This function is deprecated. Use CertificateFromBase64 or GetCertificate
// instead.
func Certificate(
certPEMBase64, keyPEMBase64 string,
certPath, keyPath string,
) ([]tls.Certificate, error) {View on GitHub (pinned to 4174065ffb)
Solutions
- Convert to PEM if needed (openssl x509 -inform der -outform pem) and ensure key is unencrypted PEM (PKCS#8: openssl pkcs8 -topk8 -nocrypt)
- Verify the pair matches: compare `openssl x509 -noout -modulus` of cert with `openssl rsa -noout -modulus` of key
- Re-encode the exact PEM files with base64 (avoid double-encoding) and test with `openssl x509` / `openssl pkey` locally
- Rotate cert and key together so they stay a matched pair
Example fix
// before
// certPEM was DER binary, key PEM encrypted -> X509KeyPair fails
// after
// openssl x509 -inform der -in cert.der -out cert.pem
// openssl pkcs8 -topk8 -nocrypt -in key.pem -out key.pem
certB64 := base64.StdEncoding.EncodeToString(pemBytes("cert.pem"))
keyB64 := base64.StdEncoding.EncodeToString(pemBytes("key.pem")) Defensive patterns
Strategy: validation
Validate before calling
func validPair(certPEM, keyPEM []byte) error {
_, err := tls.X509KeyPair(certPEM, keyPEM)
return err // run after decoding base64, before use
} Try / catch
cert, err := tlsx.CertificateFromBase64(certB64, keyB64)
if err != nil && strings.Contains(err.Error(), "X509 key pair") {
log.WithError(err).Error("cert/key are valid base64 but not a valid matching PEM pair; rotate together")
return err
} Prevention
- Always use unencrypted PEM (PKCS#8) keys supported by crypto/tls
- Rotate cert and key together; verify pair match with openssl moduli comparison
- Avoid double base64-encoding already-encoded files
When it happens
Trigger: Calling CertificateFromBase64 where the base64 decodes but the plaintext is not PEM (double-encoded base64, binary DER instead of PEM, missing -----BEGIN/END----- markers), or the key does not correspond to the certificate's public key.
Common situations: Encoding an already-base64 file twice, using a DER-encoded cert, key format not supported by crypto/tls (e.g. certain encrypted or non-PKCS#8 keys), rotated cert without rotating the key, or concatenating multiple certs in a way X509KeyPair rejects.
Related errors
- unable to load X509 key pair from files: %v
- unable to base64 decode the TLS certificate: %v
- failed to create certificate: %s
- failed to encode private key: %s
- the CA certificate does not have the client authentication e
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/b8d62716e65c5c21.
Report an issue: GitHub.