hashicorp/nomad · error
Failed to load cert/key pair: %v
Error message
Failed to load cert/key pair: %v
What it means
LoadKeyPair delegates to Config.KeyLoader.LoadKeyPair(CertFile, KeyFile) to read and parse the certificate/private-key pair into a tls.Certificate. Any failure from the loader (unreadable file, PEM parse error, mismatched key, encrypted key) is wrapped in this error. It means TLS identity files could not be loaded.
Source
Thrown at helper/tlsutil/config.go:209
return fmt.Errorf("Failed to parse any valid certificates in CA file: %s", c.CAFile)
}
return nil
}
// LoadKeyPair is used to open and parse a certificate and key file
func (c *Config) LoadKeyPair() (*tls.Certificate, error) {
if c.CertFile == "" || c.KeyFile == "" {
return nil, nil
}
if c.KeyLoader == nil {
return nil, fmt.Errorf("No Keyloader object to perform LoadKeyPair")
}
cert, err := c.KeyLoader.LoadKeyPair(c.CertFile, c.KeyFile)
if err != nil {
return nil, fmt.Errorf("Failed to load cert/key pair: %v", err)
}
return cert, err
}
// OutgoingTLSConfig generates a TLS configuration for outgoing
// requests. It will return a nil config if this configuration should
// not use TLS for outgoing connections. Provides a callback to
// fetch certificates, allowing for reloading on the fly.
func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
// If VerifyServerHostname is true, that implies VerifyOutgoing
if c.VerifyServerHostname {
c.VerifyOutgoing = true
}
if !c.VerifyOutgoing {
return nil, nil
}
// Create the tlsConfig
tlsConfig := &tls.Config{View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped %v cause and fix that specific problem (path, permission, or parse error).
- Verify the pair matches: compare modulus/public keys (openssl x509 -noout -modulus vs openssl rsa -noout -modulus).
- Validate files with openssl x509 / openssl pkey; re-export the key in an unencrypted PKCS#8/PEM format Go supports.
- Ensure CertFile holds the leaf cert (chain first) and KeyFile the corresponding private key, both readable by the process.
Example fix
// before cfg.KeyFile = "old-key.pem" // key regenerated, no longer matches cert // after cfg.CertFile = "new-cert.pem" cfg.KeyFile = "new-key.pem" // matching pair from the same issuance
Defensive patterns
Strategy: validation
Validate before calling
func validateKeyPair(certPath, keyPath string) error {
certPEM, err := os.ReadFile(certPath); if err != nil { return err }
keyPEM, err := os.ReadFile(keyPath); if err != nil { return err }
cert, err := tls.X509KeyPair(certPEM, keyPEM)
if err != nil { return fmt.Errorf("cert/key mismatch or unparsable: %w", err) }
leaf, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil { return err }
if time.Now().After(leaf.NotAfter) { return fmt.Errorf("certificate expired %s", leaf.NotAfter) }
return nil
} Try / catch
cert, err := cfg.LoadKeyPair()
if err != nil && strings.Contains(err.Error(), "Failed to load cert/key pair") {
if verr := validateKeyPair(cfg.CertFile, cfg.KeyFile); verr != nil {
return fmt.Errorf("TLS identity files invalid: %w", verr)
}
return err
} Prevention
- Validate cert/key pairs with tls.X509KeyPair (or openssl) before deployment and after each rotation.
- Always rotate cert and key together from the same issuance.
- Ensure both files are readable by the service user and use unencrypted, Go-supported key formats (PKCS#8/PEM).
- Monitor certificate expiry and rotate before NotAfter.
When it happens
Trigger: CertFile and KeyFile are set and a KeyLoader exists, but loading fails — missing/unreadable files, invalid PEM, certificate and key not matching, unsupported key format (e.g. encrypted PKCS#8 without password), or expired/invalid cert bytes.
Common situations: Wrong key paired with the cert after rotation; cert file actually containing a chain without the key or vice versa; permissions blocking the process user; keys generated with algorithms/options the Go TLS stack cannot parse.
Related errors
- Failed to read CA file: %v
- Failed to parse any valid certificates in CA file: %s
- no PEM-encoded data found
- failed to initialize Consul client config: %v
- cannot reload agent with nil configuration
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0195a9571d47a5ee.
Report an issue: GitHub.