hashicorp/nomad · error
Failed to read CA file: %v
Error message
Failed to read CA file: %v
What it means
AppendCA reads the CAFile from a TLS Config and appends its PEM certificates to the certificate pool. This error wraps any failure reading that file from disk (os.ReadFile). It means the configured CA bundle path could not be opened or read, so no CA certificates can be loaded for TLS verification.
Source
Thrown at helper/tlsutil/config.go:184
CertFile: newConf.CertFile,
KeyFile: newConf.KeyFile,
KeyLoader: newConf.GetKeyLoader(),
CipherSuites: ciphers,
MinVersion: minVersion,
}, nil
}
// AppendCA opens and parses the CA file and adds the certificates to
// the provided CertPool.
func (c *Config) AppendCA(pool *x509.CertPool) error {
if c.CAFile == "" {
return nil
}
// Read the file
data, err := os.ReadFile(c.CAFile)
if err != nil {
return fmt.Errorf("Failed to read CA file: %v", err)
}
// 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
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the path in CAFile is absolute and correct, and that the file exists (ls -l <path>).
- Fix file permissions/ownership so the process user can read it.
- Ensure the CA file is mounted/copied into containers or the correct secret is referenced.
- Confirm CAFile is a regular file, not a directory, and re-check config after rotation.
Example fix
// before config.CAFile = "ca.pem" // relative path; file not found at runtime // after config.CAFile = "/etc/consul/tls/ca.pem" // absolute, existing, readable path
Defensive patterns
Strategy: validation
Validate before calling
func validateCAFile(path string) error {
fi, err := os.Stat(path)
if err != nil { return fmt.Errorf("CA file %q: %w", path, err) }
if fi.IsDir() { return fmt.Errorf("CAFile %q is a directory", path) }
f, err := os.Open(path)
if err != nil { return fmt.Errorf("CA file not readable: %w", err) }
f.Close()
return nil
}
// call before building config: if err := validateCAFile(cfg.CAFile); err != nil { ... } Try / catch
tlsCfg, err := tlsConf.OutgoingTLSConfig()
if err != nil && strings.Contains(err.Error(), "Failed to read CA file") {
return fmt.Errorf("misconfigured CA path: %w", err)
} Prevention
- Use absolute paths for CAFile in all configurations.
- Add a startup health check that stats and reads every configured TLS file.
- Mount CA bundles explicitly into containers and verify after secret rotation.
- Ensure the service user has read permissions on cert directories.
When it happens
Trigger: OutgoingTLSConfig or IncomingTLSConfig is built with Config.CAFile set, but os.ReadFile(c.CAFile) fails — the file does not exist, the path is wrong, permissions deny read, or it is a directory.
Common situations: Typo in CAFile path; CA file not mounted into a container; wrong working directory making a relative path invalid; file removed by secret rotation; running as a user lacking read permission on the cert.
Related errors
- Failed to parse any valid certificates in CA file: %s
- Failed to load cert/key pair: %v
- no PEM-encoded data found
- failed to initialize Consul client config: %v
- failed to create stdout logfile for %q: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/da81bd4b8bda2cbf.
Report an issue: GitHub.