ory/hydra · error
unable to base64 decode the TLS private key: %v
Error message
unable to base64 decode the TLS private key: %v
What it means
CertificateFromBase64 decodes the base64-encoded private key PEM. This error is returned when the key string is not valid standard base64. The certificate decoded fine, but the key material is corrupted or not base64.
Source
Thrown at oryx/tlsx/cert.go:80
- ` + prefix + `_CERT: Base64 encoded (without padding) string of the TLS certificate (PEM encoded) to be used for HTTP over TLS (HTTPS).
Example: ` + prefix + `_CERT="-----BEGIN CERTIFICATE-----\nMIIDZTCCAk2gAwIBAgIEV5xOtDANBgkqhkiG9w0BAQ0FADA0MTIwMAYDVQQDDClP..."
- ` + 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.View on GitHub (pinned to 4174065ffb)
Solutions
- Re-encode the key: `base64 -w0 key.pem` and use that exact output
- Strip all whitespace/newlines from keyBase64 before decoding
- Check the value is standard (not URL-safe) base64 and not the raw PEM block
- Verify cert and key arguments are not swapped
Example fix
// before
keyB64 := "-----BEGIN PRIVATE KEY-----\n..." // raw PEM
// after
keyPEMBytes, _ := os.ReadFile("key.pem")
keyB64 := base64.StdEncoding.EncodeToString(keyPEMBytes) Defensive patterns
Strategy: validation
Validate before calling
func isStdBase64(s string) bool {
_, err := base64.StdEncoding.DecodeString(s)
return err == nil
}
// run before CertificateFromBase64: isStdBase64(keyBase64) Try / catch
cert, err := tlsx.CertificateFromBase64(certB64, keyB64)
if err != nil && strings.Contains(err.Error(), "base64 decode the TLS private key") {
log.Error("keyBase64 is not valid standard base64; re-encode with `base64 -w0 key.pem`")
return err
} Prevention
- Base64-encode the key with `base64 -w0 key.pem` at deploy time
- Watch for env/YAML quoting that truncates or mangles the key
- Keep cert and key values clearly named to avoid swapping them
When it happens
Trigger: Calling CertificateFromBase64 (directly or through Certificate/GetCertFunc) where certBase64 is valid but keyBase64 fails base64.StdEncoding.DecodeString — e.g. raw PEM key pasted, URL-safe base64, stray whitespace, or an empty/garbage key value.
Common situations: Only the key was re-generated/re-uploaded and pasted as raw PEM, env var containing the key got truncated, quoting issues in YAML/env files mangling the key string, or swapped cert/key order.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- unable to load TLS certificate for interface %s: %w
- unable to base64 decode the TLS certificate: %v
- no tls configuration was found
- tls configuration is invalid
- issuer URL scheme must be HTTPS unless development mode is e
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/c41374197129c1de.
Report an issue: GitHub.