{"record":{"id":"b8d62716e65c5c21","repo":"ory/hydra","slug":"unable-to-load-x509-key-pair-v","errorCode":null,"errorMessage":"unable to load X509 key pair: %v","messagePattern":"unable to load X509 key pair: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/tlsx/cert.go","lineNumber":84,"sourceCode":"- ` + prefix + `_KEY: Base64 encoded (without padding) string of the private key (PEM encoded) to be used for HTTP over TLS (HTTPS).\n\tExample: ` + prefix + `_KEY=\"-----BEGIN ENCRYPTED PRIVATE KEY-----\\nMIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDg...\"\n`\n}\n\n// CertificateFromBase64 loads a TLS certificate from a base64-encoded string of\n// the PEM representations of the cert and key.\nfunc CertificateFromBase64(certBase64, keyBase64 string) (tls.Certificate, error) {\n\tcertPEM, err := base64.StdEncoding.DecodeString(certBase64)\n\tif err != nil {\n\t\treturn tls.Certificate{}, fmt.Errorf(\"unable to base64 decode the TLS certificate: %v\", err)\n\t}\n\tkeyPEM, err := base64.StdEncoding.DecodeString(keyBase64)\n\tif err != nil {\n\t\treturn tls.Certificate{}, fmt.Errorf(\"unable to base64 decode the TLS private key: %v\", err)\n\t}\n\tcert, err := tls.X509KeyPair(certPEM, keyPEM)\n\tif err != nil {\n\t\treturn tls.Certificate{}, fmt.Errorf(\"unable to load X509 key pair: %v\", err)\n\t}\n\treturn cert, nil\n}\n\n// [deprecated] Certificate returns a TLS Certificate by looking at its\n// arguments. If both certPEMBase64 and keyPEMBase64 are not empty and contain\n// base64-encoded PEM representations of a cert and key, respectively, that key\n// pair is returned. Otherwise, if certPath and keyPath point to PEM files, the\n// key pair is loaded from those. Returns ErrNoCertificatesConfigured if all\n// arguments are empty, and ErrInvalidCertificateConfiguration if the arguments\n// are inconsistent.\n//\n// This function is deprecated. Use CertificateFromBase64 or GetCertificate\n// instead.\nfunc Certificate(\n\tcertPEMBase64, keyPEMBase64 string,\n\tcertPath, keyPath string,\n) ([]tls.Certificate, error) {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/tlsx/cert.go#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n// certPEM was DER binary, key PEM encrypted -> X509KeyPair fails\n// after\n// openssl x509 -inform der -in cert.der -out cert.pem\n// openssl pkcs8 -topk8 -nocrypt -in key.pem -out key.pem\ncertB64 := base64.StdEncoding.EncodeToString(pemBytes(\"cert.pem\"))\nkeyB64 := base64.StdEncoding.EncodeToString(pemBytes(\"key.pem\"))","handlingStrategy":"validation","validationCode":"func validPair(certPEM, keyPEM []byte) error {\n    _, err := tls.X509KeyPair(certPEM, keyPEM)\n    return err // run after decoding base64, before use\n}","typeGuard":null,"tryCatchPattern":"cert, err := tlsx.CertificateFromBase64(certB64, keyB64)\nif err != nil && strings.Contains(err.Error(), \"X509 key pair\") {\n    log.WithError(err).Error(\"cert/key are valid base64 but not a valid matching PEM pair; rotate together\")\n    return err\n}","preventionTips":["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"],"tags":["tls","x509","certificate","key-mismatch"],"backgroundTag":"tls-certificate-load-failed","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}