{"record":{"id":"8021fbb79c859c33","repo":"nats-io/nats-server","slug":"error-parsing-certificate-d-d-v","errorCode":null,"errorMessage":"error parsing certificate %d/%d: %v","messagePattern":"error parsing certificate (.+?)/(.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/opts.go","lineNumber":5864,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"error parsing certificate: %v\", err)\n\t\t}\n\t\tconfig.Certificates = []tls.Certificate{cert}\n\tcase tc.CertStore != certstore.STOREEMPTY:\n\t\terr := certstore.TLSConfig(tc.CertStore, tc.CertMatchBy, tc.CertMatch, tc.CaCertsMatch, tc.CertMatchSkipInvalid, &config)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase tc.Certificates != nil:\n\t\t// Multiple certificate support.\n\t\tconfig.Certificates = make([]tls.Certificate, len(tc.Certificates))\n\t\tfor i, certPair := range tc.Certificates {\n\t\t\tcert, err := tls.LoadX509KeyPair(certPair.CertFile, certPair.KeyFile)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing X509 certificate/key pair %d/%d: %v\", i+1, len(tc.Certificates), err)\n\t\t\t}\n\t\t\tcert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing certificate %d/%d: %v\", i+1, len(tc.Certificates), err)\n\t\t\t}\n\t\t\tconfig.Certificates[i] = cert\n\t\t}\n\t}\n\n\t// Require client certificates as needed\n\tif tc.Verify {\n\t\tconfig.ClientAuth = tls.RequireAndVerifyClientCert\n\t}\n\t// Add in CAs if applicable.\n\tif tc.CaFile != _EMPTY_ {\n\t\trootPEM, err := os.ReadFile(tc.CaFile)\n\t\tif err != nil || rootPEM == nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpool := x509.NewCertPool()\n\t\tok := pool.AppendCertsFromPEM(rootPEM)\n\t\tif !ok {","sourceCodeStart":5846,"sourceCodeEnd":5882,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/opts.go#L5846-L5882","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: cert.pem contains a CSR\nCertFile: server.csr\n// after\nCertFile: server.crt  // openssl x509 -in server.crt -noout succeeds","handlingStrategy":"validation","validationCode":"// Validate each cert file before configuring the server\nfor _, pair := range certPairs {\n    pemBytes, err := os.ReadFile(pair.CertFile)\n    if err != nil { return err }\n    block, _ := pem.Decode(pemBytes)\n    if block == nil || block.Type != \"CERTIFICATE\" {\n        return fmt.Errorf(\"%s: no CERTIFICATE PEM block\", pair.CertFile)\n    }\n    if _, err := x509.ParseCertificate(block.Bytes); err != nil {\n        return fmt.Errorf(\"%s: invalid certificate: %v\", pair.CertFile, err)\n    }\n}","typeGuard":"func isPEMCertificate(b []byte) bool {\n    block, _ := pem.Decode(b)\n    if block == nil || block.Type != \"CERTIFICATE\" { return false }\n    _, err := x509.ParseCertificate(block.Bytes)\n    return err == nil\n}","tryCatchPattern":"cert, err := tls.LoadX509KeyPair(certFile, keyFile)\nif err != nil {\n    return fmt.Errorf(\"loading TLS key pair %s: %w\", certFile, err)\n}\nif cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil {\n    return fmt.Errorf(\"certificate %s is corrupt, re-export it: %w\", certFile, err)\n}","preventionTips":["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."],"tags":["tls","certificate","x509","config"],"backgroundTag":"x509-certificate-parse-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}