ory/hydra · error

unable to base64 decode the TLS certificate: %v

Error message

unable to base64 decode the TLS certificate: %v

What it means

CertificateFromBase64 decodes base64-encoded PEM blobs for a TLS cert and key. This error is returned when the certificate string is not valid base64 (base64.StdEncoding.DecodeString fails), before any PEM parsing happens. It means the supplied cert material is corrupted or not base64-encoded at all.

Source

Thrown at oryx/tlsx/cert.go:76

	Example: ` + prefix + `_CERT_PATH=~/cert.pem

- ` + prefix + `_KEY_PATH: The path to the TLS private key (pem encoded).
	Example: ` + prefix + `_KEY_PATH=~/key.pem

- ` + 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

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Re-encode the cert with base64.StdEncoding: `base64 -w0 cert.pem` and use that exact string
  2. Strip whitespace/newlines from the value before use (strings map or base64.NewDecoder with StdEncoding after cleanup)
  3. Verify you are not passing URL-safe base64; convert it to standard base64 if so
  4. Confirm cert and key values are not swapped

Example fix

// before
certB64 := "-----BEGIN CERTIFICATE-----\nMIIB..." // raw PEM, not base64
cert, err := CertificateFromBase64(certB64, keyB64)
// after
certPEM, _ := os.ReadFile("cert.pem")
certB64 := base64.StdEncoding.EncodeToString(certPEM)
cert, err := CertificateFromBase64(certB64, keyB64)
Defensive patterns

Strategy: validation

Validate before calling

func isStdBase64(s string) bool {
    _, err := base64.StdEncoding.DecodeString(s)
    return err == nil
}
// run before CertificateFromBase64: isStdBase64(certBase64)

Try / catch

cert, err := tlsx.CertificateFromBase64(certB64, keyB64)
if err != nil && strings.Contains(err.Error(), "base64 decode the TLS certificate") {
    // strip whitespace / re-encode and retry once
    cleaned := strings.Map(func(r rune) rune { if r == '\n' || r == '\r' || r == ' ' { return -1 }; return r }, certB64)
    cert, err = tlsx.CertificateFromBase64(cleaned, keyB64)
}

Prevention

When it happens

Trigger: Calling CertificateFromBase64(certBase64, keyBase64) (directly or via Certificate/GetCertFunc when TLS_CERT and TLS_KEY style base64 inputs are configured) with a cert string containing whitespace/newlines in the wrong place, URL-safe base64 instead of standard base64, or a raw PEM block (-----BEGIN CERTIFICATE-----) instead of base64 of the PEM.

Common situations: Pasting the PEM file itself instead of base64-encoding it, using `openssl base64` variants that insert line breaks not stripped correctly, env var values with surrounding quotes or trailing newline, or swapping cert/key values.

Understand the failure class

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/f83563cbcd655d3f. Report an issue: GitHub.