nats-io/nats-server · error
error parsing X509 certificate/key pair: %v
Error message
error parsing X509 certificate/key pair: %v
What it means
tls.LoadX509KeyPair failed while loading the configured cert_file/key_file, and the server wraps the underlying error with this message. The files may be unreadable, malformed PEM, or mismatched cert/key.
Source
Thrown at server/opts.go:5842
config := tls.Config{
MinVersion: tls.VersionTLS12,
CipherSuites: tc.Ciphers,
CurvePreferences: tc.CurvePreferences,
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)View on GitHub (pinned to 3a66a489d2)
Solutions
- Verify both files exist, are valid PEM, and readable by the server user (the wrapped %v names the underlying cause)
- Check that cert and key form a matching pair (compare public key / modulus)
- Decrypt or remove passphrase from the key file
- Re-export the certificate chain including intermediates
Defensive patterns
Strategy: validation
Validate before calling
if _, err := tls.LoadX509KeyPair(cfg.TLS.CertFile, cfg.TLS.KeyFile); err != nil {
return fmt.Errorf("pre-flight keypair check failed: %w", err)
} Try / catch
if _, err := tls.LoadX509KeyPair(cert, key); err != nil {
return fmt.Errorf("invalid cert/key pair %s/%s: %w", cert, key, err)
} Prevention
- Pre-flight load key pairs at deploy time
- Check file permissions for the server's run user
- Ensure key is unencrypted and matches the certificate
- Include full chain (leaf + intermediates) in cert_file
When it happens
Trigger: parseTLS calling tls.LoadX509KeyPair(tc.CertFile, tc.KeyFile) which returns a non-nil error (bad permissions, invalid PEM blocks, encrypted keys, mismatched pair).
Common situations: Wrong file permissions; concatenating cert and key into wrong files; key encrypted with a passphrase; files truncated by failed deployments.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- error parsing certificate: %v
- error parsing X509 certificate/key pair %d/%d: %v
- error parsing certificate %d/%d: %v
- invalid type name: %+v
- invalid type value: %+v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/94f7158014b7aab1.
Report an issue: GitHub.