hashicorp/nomad · error
No Keyloader object to perform LoadKeyPair
Error message
No Keyloader object to perform LoadKeyPair
What it means
LoadKeyPair loads CertFile/KeyFile through the pluggable KeyLoader. If CertFile and KeyFile are both set but Config.KeyLoader is nil, there is no object to perform the load, so this error is returned. It is a configuration/initialization bug: TLS cert loading was requested but the loader dependency was never injected.
Source
Thrown at helper/tlsutil/config.go:204
// Read certificates and return an error if no valid certificates were
// found. Unfortunately it is very difficult to return meaningful
// errors as PEM files are extremely permissive.
if !pool.AppendCertsFromPEM(data) {
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
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set Config.KeyLoader to the library's default key loader before calling LoadKeyPair.
- If no cert/key pair is needed, clear CertFile/KeyFile (LoadKeyPair then returns nil, nil).
- Check how the Config is built/decoded to ensure the KeyLoader field is populated (it is not a serialized field).
- In tests, use the same initialization helper production code uses instead of a zero-value Config.
Example fix
// before
cfg := &tlsutil.Config{CertFile: cert, KeyFile: key}
cert, err := cfg.LoadKeyPair() // No Keyloader object
// after
cfg := &tlsutil.Config{CertFile: cert, KeyFile: key, KeyLoader: &tlsutil.FileKeyLoader{}}
cert, err := cfg.LoadKeyPair() Defensive patterns
Strategy: validation
Validate before calling
func (c *tlsutil.Config) validate() error {
if c.CertFile != "" && c.KeyFile != "" && c.KeyLoader == nil {
return errors.New("CertFile/KeyFile set but KeyLoader is nil; set a KeyLoader")
}
return nil
}
// call cfg.validate() before LoadKeyPair / TLS config generation Type guard
func hasUsableKeyLoader(c *tlsutil.Config) bool {
return c.CertFile == "" || c.KeyFile == "" || c.KeyLoader != nil
} Try / catch
cert, err := cfg.LoadKeyPair()
if err != nil && err.Error() == "No Keyloader object to perform LoadKeyPair" {
return fmt.Errorf("tls config not initialized: %w", err)
} Prevention
- Always construct tlsutil.Config through the library's constructor/default initializer, not a zero-value struct literal.
- Set KeyLoader explicitly in code-based configuration and test fixtures.
- Add a config-validate step that rejects CertFile/KeyFile without a KeyLoader at startup.
- When copying Config structs, copy/replace the loader field too.
When it happens
Trigger: Building a Config with both CertFile and KeyFile set and calling LoadKeyPair (directly or via OutgoingTLSConfig/IncomingTLSConfig) while KeyLoader remains nil — typically a hand-constructed Config instead of one initialized with the default loader.
Common situations: Constructing tlsutil.Config{} manually in code or tests and forgetting to set KeyLoader; upgrading library versions where the default loader is no longer auto-populated; copying config structs field-by-field and dropping the loader.
Related errors
- failed to initialize Consul client config: %v
- cannot reload agent with nil configuration
- https_handshake_timeout must be >= 0
- failed to initialize HTTP server TLS configuration: %s
- failed to configure TLS: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/fc3fb869850e0bde.
Report an issue: GitHub.