nats-io/nats-server · error

error parsing certificate: %v

Error message

error parsing certificate: %v

What it means

After successfully loading the key pair, the server parses the first DER certificate into an x509.Certificate leaf (needed for SAN-based matching). If x509.ParseCertificate fails, this error is returned. It means the certificate bytes are corrupt or not a supported X.509 structure.

Source

Thrown at server/opts.go:5846

		InsecureSkipVerify: tc.Insecure,
	}

	switch {
	case tc.CertFile != _EMPTY_ && tc.CertStore != certstore.STOREEMPTY:
		return nil, certstore.ErrConflictCertFileAndStore
	case tc.CertFile != _EMPTY_ && tc.KeyFile == _EMPTY_:
		return nil, fmt.Errorf("missing 'key_file' in TLS configuration")
	case tc.CertFile == _EMPTY_ && tc.KeyFile != _EMPTY_:
		return nil, fmt.Errorf("missing 'cert_file' in TLS configuration")
	case tc.CertFile != _EMPTY_ && tc.KeyFile != _EMPTY_:
		// Now load in cert and private key
		cert, err := tls.LoadX509KeyPair(tc.CertFile, tc.KeyFile)
		if err != nil {
			return nil, fmt.Errorf("error parsing X509 certificate/key pair: %v", err)
		}
		cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
		if err != nil {
			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)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Inspect cert_file with 'openssl x509 -in server.pem -text -noout' and re-export a clean PEM
  2. Ensure cert_file starts with the leaf certificate, not an intermediate
  3. Replace the certificate file from a trusted source and reload
Defensive patterns

Strategy: validation

Validate before calling

pemBytes, _ := os.ReadFile(cfg.TLS.CertFile)
block, _ := pem.Decode(pemBytes)
if block == nil || block.Type != "CERTIFICATE" { return errors.New("cert_file missing CERTIFICATE PEM block") }
if _, err := x509.ParseCertificate(block.Bytes); err != nil { return err }

Try / catch

if _, err := x509.ParseCertificate(block.Bytes); err != nil {
  return fmt.Errorf("malformed certificate in %s: %w", path, err)
}

Prevention

When it happens

Trigger: parseTLS: cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0]) returning err, i.e. malformed or unsupported certificate data in cert_file.

Common situations: Corrupted certificates from truncated downloads; exotic encodings or unsupported signature algorithms; mis-ordered PEM concatenation causing wrong first block.

Understand the failure class

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/fedc58e570773f70. Report an issue: GitHub.