nats-io/nats-server · error
error parsing certificate %d/%d: %v
Error message
error parsing certificate %d/%d: %v
What it means
Returned by NATS server TLS option setup (ProcessOptionsFile/TLS config path in server/opts.go) after a key pair loads but the embedded certificate fails x509.ParseCertificate. tls.LoadX509KeyPair only checks PEM block structure; this second parse decodes the actual X.509 ASN.1 DER, so a structurally valid PEM wrapping corrupt or non-certificate DER fails here. The index i+1/len identifies which certificate pair in tc.Certificates failed.
Source
Thrown at server/opts.go:5864
return nil, fmt.Errorf("error parsing certificate: %v", err)
}
config.Certificates = []tls.Certificate{cert}
case tc.CertStore != certstore.STOREEMPTY:
err := certstore.TLSConfig(tc.CertStore, tc.CertMatchBy, tc.CertMatch, tc.CaCertsMatch, tc.CertMatchSkipInvalid, &config)
if err != nil {
return nil, err
}
case tc.Certificates != nil:
// Multiple certificate support.
config.Certificates = make([]tls.Certificate, len(tc.Certificates))
for i, certPair := range tc.Certificates {
cert, err := tls.LoadX509KeyPair(certPair.CertFile, certPair.KeyFile)
if err != nil {
return nil, fmt.Errorf("error parsing X509 certificate/key pair %d/%d: %v", i+1, len(tc.Certificates), err)
}
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return nil, fmt.Errorf("error parsing certificate %d/%d: %v", i+1, len(tc.Certificates), err)
}
config.Certificates[i] = cert
}
}
// Require client certificates as needed
if tc.Verify {
config.ClientAuth = tls.RequireAndVerifyClientCert
}
// Add in CAs if applicable.
if tc.CaFile != _EMPTY_ {
rootPEM, err := os.ReadFile(tc.CaFile)
if err != nil || rootPEM == nil {
return nil, err
}
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM(rootPEM)
if !ok {View on GitHub (pinned to 3a66a489d2)
Solutions
- Verify the cert file with `openssl x509 -in cert.pem -text -noout`; regenerate or re-export it if it fails.
- Ensure cert and key files were not swapped: the CertFile must contain -----BEGIN CERTIFICATE----- blocks.
- Re-copy/download the certificate from the issuing source and confirm file integrity (checksum).
- Re-issue the certificate from the CA if the DER is genuinely corrupt.
Example fix
// before: cert.pem contains a CSR CertFile: server.csr // after CertFile: server.crt // openssl x509 -in server.crt -noout succeeds
Defensive patterns
Strategy: validation
Validate before calling
// Validate each cert file before configuring the server
for _, pair := range certPairs {
pemBytes, err := os.ReadFile(pair.CertFile)
if err != nil { return err }
block, _ := pem.Decode(pemBytes)
if block == nil || block.Type != "CERTIFICATE" {
return fmt.Errorf("%s: no CERTIFICATE PEM block", pair.CertFile)
}
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
return fmt.Errorf("%s: invalid certificate: %v", pair.CertFile, err)
}
} Type guard
func isPEMCertificate(b []byte) bool {
block, _ := pem.Decode(b)
if block == nil || block.Type != "CERTIFICATE" { return false }
_, err := x509.ParseCertificate(block.Bytes)
return err == nil
} Try / catch
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return fmt.Errorf("loading TLS key pair %s: %w", certFile, err)
}
if cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil {
return fmt.Errorf("certificate %s is corrupt, re-export it: %w", certFile, err)
} Prevention
- Run `openssl x509 -in cert.pem -text -noout` on every cert before deploying.
- Never concatenate CSRs, keys, or chains into the CertFile.
- Verify checksums after transferring certificates between hosts.
When it happens
Trigger: Configuring server TLS via the certificates option with a cert file whose leaf certificate bytes are corrupt, truncated, or not a real certificate (e.g. a CSR or a private key pasted into the cert file), while the key pair itself still loads.
Common situations: Manually concatenated PEM files, certificates re-saved through editors that mangled base64, wrong file swapped in (key instead of cert), corrupted files from interrupted scp/copy, or certs exported in a non-PEM container then renamed .crt.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- error parsing X509 certificate/key pair: %v
- error parsing certificate: %v
- error parsing X509 certificate/key pair %d/%d: %v
- unable to plug TLS verify connection, config is nil
- OCSP peer verification for client connections requires TLS v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/8021fbb79c859c33.
Report an issue: GitHub.