cloudflare/pingora · error
Failed to parse certificate from DER format.
Error message
Failed to parse certificate from DER format.
What it means
get_organization_serial_bytes() in pingora's rustls TLS utils parses a DER-encoded X509 certificate with x509-parser and expects success. DER parsing fails when the bytes are not a complete valid DER certificate — PEM text (-----BEGIN----- armor) or base64 passed where raw DER is required, truncated/corrupted files, or empty input. The panic aborts the calling task.
Source
Thrown at pingora-core/src/utils/tls/rustls.rs:62
get_organization_x509(x509cert.borrow_cert())
}
/// Return the organization associated with the X509 certificate.
/// see https://en.wikipedia.org/wiki/X.509#Structure_of_a_certificate
pub fn get_organization_x509(x509cert: &X509Certificate<'_>) -> Option<String> {
x509cert
.subject
.iter_organization()
.filter_map(|a| a.as_str().ok())
.map(|a| a.to_string())
.reduce(|cur, next| cur + &next)
}
/// Return the organization associated with the X509 certificate (as bytes).
/// see https://en.wikipedia.org/wiki/X.509#Structure_of_a_certificate
pub fn get_organization_serial_bytes(cert: &[u8]) -> Result<(Option<String>, String)> {
let (_, x509cert) = x509_parser::certificate::X509Certificate::from_der(cert)
.expect("Failed to parse certificate from DER format.");
get_organization_serial_x509(&x509cert)
}
/// Return the organization unit associated with the X509 certificate.
/// see https://en.wikipedia.org/wiki/X.509#Structure_of_a_certificate
pub fn get_organization_unit(x509cert: &WrappedX509) -> Option<String> {
x509cert
.borrow_cert()
.subject
.iter_organizational_unit()
.filter_map(|a| a.as_str().ok())
.map(|a| a.to_string())
.reduce(|cur, next| cur + &next)
}
/// Get a combination of the common names for the given certificate
/// see https://en.wikipedia.org/wiki/X.509#Structure_of_a_certificateView on GitHub (pinned to 0046038bd4)
Solutions
- Ensure the input is DER: `openssl x509 -in cert.pem -outform DER -out cert.der` and pass those bytes
- Verify before the call: `openssl x509 -inform DER -in cert.der -noout` must succeed
- If you only have PEM, decode the CERTIFICATE block's base64 payload first, or parse fallibly yourself with X509Certificate::from_der instead of hitting pingora's expect
- Check for truncation/corruption — compare size and checksum against the cert source
Example fix
// before: PEM text passed where DER is expected — panics let (org, serial) = get_organization_serial_bytes(&pem_bytes); // after: extract the DER payload from the PEM block first use x509_parser::pem::Pem; let pem = Pem::iter_from_buffer(&pem_bytes).next().unwrap().unwrap(); let (org, serial) = get_organization_serial_bytes(&pem.contents);
Defensive patterns
Strategy: validation
Validate before calling
// Reject invalid DER before calling helpers that expect() it
fn is_valid_der_cert(bytes: &[u8]) -> bool {
x509_parser::certificate::X509Certificate::from_der(bytes).is_ok()
}
if !is_valid_der_cert(&cert_bytes) {
anyhow::bail!("cert is not valid DER — convert PEM first: openssl x509 -outform DER");
} Type guard
fn is_der_cert(bytes: &[u8]) -> bool {
// cheap structural check: DER SEQUENCE tag, then full parse for certainty
bytes.first() == Some(&0x30)
&& x509_parser::certificate::X509Certificate::from_der(bytes).is_ok()
} Try / catch
// If you must call code that may panic on bad certs, isolate it
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
get_organization_serial_bytes(&cert_bytes)
}));
match res {
Ok(v) => { /* use org/serial */ }
Err(_) => { /* bad DER input: log which cert failed and skip */ }
} Prevention
- Standardize on one encoding in your pipeline and convert at the boundary (openssl x509 -outform DER)
- Validate certificates during config load, never on the serving path
- Never assume chain files are single certs — parse per block
When it happens
Trigger: Calling get_organization_serial_bytes(cert_bytes) (or a pingora path extracting org/serial from a cert) with bytes that are PEM text, base64, truncated, or otherwise not strict DER.
Common situations: Reading a .pem file into bytes and passing them where DER is expected; chain files where the wrong offset/bytes are used; certificates corrupted in transit or by secrets-injection systems; empty files from failed mounts.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse certificate from DER format.
- Failed to parse PEM
- invalid ca pem
- Failed to build listeners
- No tls feature was specified
AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16).
Data as JSON: /api/errors/ab7cc04077749aa8.
Report an issue: GitHub.