nsqio/nsq · error
failed to append certificate to pool
Error message
failed to append certificate to pool
What it means
nsqd builds its server-side TLS config in buildTLSConfig (nsqd/nsqd.go). When --tls-root-ca-file is set, it reads the file and calls x509.CertPool.AppendCertsFromPEM to seed ClientCAs, which is used to verify client certificates when --tls-client-auth-policy requires or requests client certs. AppendCertsFromPEM returns false (no error value) when the file contains no parseable CERTIFICATE PEM blocks, so nsqd cannot build the pool and startup aborts. The file was read successfully; only its contents are wrong.
Source
Thrown at nsqd/nsqd.go:776
tlsClientAuthPolicy = tls.RequireAnyClientCert
case "require-verify":
tlsClientAuthPolicy = tls.RequireAndVerifyClientCert
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tlsClientAuthPolicy,
MinVersion: opts.TLSMinVersion,
}
if opts.TLSRootCAFile != "" {
tlsCertPool := x509.NewCertPool()
caCertFile, err := os.ReadFile(opts.TLSRootCAFile)
if err != nil {
return nil, err
}
if !tlsCertPool.AppendCertsFromPEM(caCertFile) {
return nil, errors.New("failed to append certificate to pool")
}
tlsConfig.ClientCAs = tlsCertPool
}
return tlsConfig, nil
}
func buildClientTLSConfig(opts *Options) (*tls.Config, error) {
tlsConfig := &tls.Config{
MinVersion: opts.TLSMinVersion,
}
if opts.TLSRootCAFile != "" {
tlsCertPool := x509.NewCertPool()
caCertFile, err := os.ReadFile(opts.TLSRootCAFile)
if err != nil {
return nil, err
}View on GitHub (pinned to 85cf10c09c)
Solutions
- Verify the file actually contains PEM certificates: 'openssl x509 -in /path/ca.pem -noout -subject' (for DER use 'openssl x509 -inform der -in ca.der -out ca.pem' to convert).
- Check you referenced the CA certificate, not the server key/cert or a CSR, in --tls-root-ca-file.
- If the file is a bundle, confirm each block parses: 'grep -c "BEGIN CERTIFICATE" ca.pem' should be >= 1 and openssl should read every block.
- Re-run nsqd; startup now proceeds past TLS config.
Example fix
# before (DER file or wrong file) nsqd --tls-root-ca-file=/etc/nsq/ca.crt # ca.crt is DER-encoded -> AppendCertsFromPEM fails # after openssl x509 -inform der -in /etc/nsq/ca.der -out /etc/nsq/ca.pem nsqd --tls-root-ca-file=/etc/nsq/ca.pem
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: ensure the CA file nsqd will load parses as PEM certificates
func validPEMCAs(path string) bool {
data, err := os.ReadFile(path)
if err != nil {
return false
}
return x509.NewCertPool().AppendCertsFromPEM(data)
}
if !validPEMCAs(opts.TLSRootCAFile) {
return fmt.Errorf("%s is not a PEM CA bundle; convert DER or fix the file", opts.TLSRootCAFile)
} Try / catch
// in process supervisors / test harnesses around nsqd startup
if err := nsqd.New(opts); err != nil {
if strings.Contains(err.Error(), "failed to append certificate to pool") {
log.Printf("TLS CA file %s is not valid PEM — regenerate/convert it", opts.TLSRootCAFile)
}
return err
} Prevention
- Keep CA files in PEM (not DER) in your config management from the start.
- Add a CI step that runs AppendCertsFromPEM on every shipped TLS file before deploy.
- Name files explicitly (ca.pem, server-key.pem) so the wrong artifact is never wired into --tls-root-ca-file.
When it happens
Trigger: Starting nsqd with --tls-root-ca-file pointing at a file whose contents are not PEM CERTIFICATE blocks: a DER/binary CA cert, a PEM with only PRIVATE KEY or CSR blocks, an empty or truncated file, or a file with mangled BEGIN/END lines or Windows line-corruption.
Common situations: Ops copies the server key/cert instead of the CA cert into the path; a cert downloaded from an internal CA arrives as DER (.crt binary) while Go only accepts PEM; concatenating files and losing the footer line '-----END CERTIFICATE-----'; passing the fullchain in a format produced by a different tool.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to AppendCertsFromPEM %s
- unknown tlsVersionOption %q
- failed to LoadX509KeyPair %s, %s - %s
- cannot flock directory %s - %s (possibly in use by another i
- failed to read TLS root CA file %s - %s
AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16).
Data as JSON: /api/errors/0e7c72eec1e2da60.
Report an issue: GitHub.