nsqio/nsq · error
failed to read TLS root CA file %s - %s
Error message
failed to read TLS root CA file %s - %s
What it means
nsqadmin's New reads --http-client-tls-root-ca-file with os.ReadFile when the flag is non-empty, to build the RootCAs pool used for outbound HTTPS to nsqd/nsqlookupd. If the read fails, startup aborts with 'failed to read TLS root CA file %s - %s' including the underlying os error, which tells you whether it was missing (no such file), unreadable (permission denied), or e.g. a directory. Note this is a plain file read — a parse failure later produces the separate 'failed to AppendCertsFromPEM' error.
Source
Thrown at nsqadmin/nsqadmin.go:75
return nil, errors.New("--http-client-tls-cert must be specified with --http-client-tls-key")
}
n.httpClientTLSConfig = &tls.Config{
InsecureSkipVerify: opts.HTTPClientTLSInsecureSkipVerify,
}
if opts.HTTPClientTLSCert != "" && opts.HTTPClientTLSKey != "" {
cert, err := tls.LoadX509KeyPair(opts.HTTPClientTLSCert, opts.HTTPClientTLSKey)
if err != nil {
return nil, fmt.Errorf("failed to LoadX509KeyPair %s, %s - %s",
opts.HTTPClientTLSCert, opts.HTTPClientTLSKey, err)
}
n.httpClientTLSConfig.Certificates = []tls.Certificate{cert}
}
if opts.HTTPClientTLSRootCAFile != "" {
tlsCertPool := x509.NewCertPool()
caCertFile, err := os.ReadFile(opts.HTTPClientTLSRootCAFile)
if err != nil {
return nil, fmt.Errorf("failed to read TLS root CA file %s - %s",
opts.HTTPClientTLSRootCAFile, err)
}
if !tlsCertPool.AppendCertsFromPEM(caCertFile) {
return nil, fmt.Errorf("failed to AppendCertsFromPEM %s", opts.HTTPClientTLSRootCAFile)
}
n.httpClientTLSConfig.RootCAs = tlsCertPool
}
for _, address := range opts.NSQLookupdHTTPAddresses {
_, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
return nil, fmt.Errorf("failed to resolve --lookupd-http-address (%s) - %s", address, err)
}
}
for _, address := range opts.NSQDHTTPAddresses {
_, err := net.ResolveTCPAddr("tcp", address)
if err != nil {View on GitHub (pinned to 85cf10c09c)
Solutions
- Check existence and readability as the nsqadmin user: 'sudo -u nsqadmin test -r /path/ca.pem && echo ok'.
- Fix the path/permissions (or mount the secret) and confirm with 'ls -l /path/ca.pem'.
- If the target uses a private CA, ensure that CA's PEM was actually copied to this host — node certs are not enough.
- Restart nsqadmin; read success moves you past this error.
Example fix
# before nsqadmin --http-client-tls-root-ca-file=/etc/nsq/tls/root-ca.pem # failed to read TLS root CA file /etc/nsq/tls/root-ca.pem - open ...: no such file or directory # after sudo install -m 0644 ca/root-ca.pem /etc/nsq/tls/root-ca.pem sudo -u nsqadmin test -r /etc/nsq/tls/root-ca.pem && echo readable nsqadmin --http-client-tls-root-ca-file=/etc/nsq/tls/root-ca.pem
Defensive patterns
Strategy: validation
Validate before calling
// pre-start: readability check as the service user
fi, err := os.Stat(path)
if err != nil || fi.IsDir() || fi.Mode().Perm()&0o400 == 0 {
return fmt.Errorf("CA file %s missing, a directory, or unreadable", path)
} Try / catch
if err := startNsqadmin(cfg); err != nil && strings.Contains(err.Error(), "failed to read TLS root CA file") {
return fmt.Errorf("fix path/permissions on %s (mount, chmod, SELinux) then restart", cfg.HTTPClientTLSRootCAFile)
} Prevention
- Mount CA secrets read-only and verify presence in an initContainer.
- Test file readability as the daemon user in deploy scripts.
- Keep TLS material paths identical across hosts via config management.
When it happens
Trigger: Pointing --http-client-tls-root-ca-file at a path that does not exist on the nsqadmin host, a file without read permission for the nsqadmin user, or a path that is a directory (e.g. trailing slash in a template). Distinct from a bad-PEM error: this fires before parsing, purely on os.ReadFile.
Common situations: Container images missing the mounted CA volume; paths written for a different host in Ansible/Chef; SELinux denying reads of custom CA locations; a typo'd absolute path; the file existing only on the nsqd nodes, not where nsqadmin runs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to LoadX509KeyPair %s, %s - %s
- failed to AppendCertsFromPEM %s
- failed to append certificate to pool
- unknown tlsVersionOption %q
- cannot flock directory %s - %s (possibly in use by another i
AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16).
Data as JSON: /api/errors/d115810767665cb2.
Report an issue: GitHub.