t8y2/dbx · error
read Neo4j CA certificate: %w
Error message
read Neo4j CA certificate: %w
What it means
neo4jTLSConfigurer (called from openDriver) reads the CA certificate file at params.CACertPath to build the TLS trust pool. If os.ReadFile fails — missing file, wrong path, or permission denied — the driver wraps the OS error as 'read Neo4j CA certificate: ...'.
Source
Thrown at agents/drivers/neo4j-go/driver.go:75
driverConfig.MaxConnectionLifetime = time.Hour
driverConfig.TelemetryDisabled = true
}}
tlsConfigurer, err := neo4jTLSConfigurer(params)
if err != nil {
return nil, err
}
if tlsConfigurer != nil {
configurers = append(configurers, tlsConfigurer)
}
return neo4j.NewDriver(uri, authToken, configurers...)
}
func neo4jTLSConfigurer(params connectParams) (func(*config.Config), error) {
var tlsConfig *tls.Config
if params.CACertPath != "" {
certificate, err := os.ReadFile(params.CACertPath)
if err != nil {
return nil, fmt.Errorf("read Neo4j CA certificate: %w", err)
}
roots, err := x509.SystemCertPool()
if err != nil || roots == nil {
roots = x509.NewCertPool()
}
if !roots.AppendCertsFromPEM(certificate) {
return nil, errors.New("Neo4j CA certificate contains no valid PEM certificate")
}
tlsConfig = &tls.Config{MinVersion: tls.VersionTLS12, RootCAs: roots}
}
var clientCertificateProvider neo4jauth.ClientCertificateProvider
if params.ClientCertPath != "" || params.ClientKeyPath != "" {
if params.ClientCertPath == "" || params.ClientKeyPath == "" {
return nil, errors.New("both client certificate and client key are required")
}
provider, err := neo4jauth.NewStaticClientCertificateProvider(neo4jauth.ClientCertificate{
CertFile: params.ClientCertPath,
KeyFile: params.ClientKeyPath,View on GitHub (pinned to c0390bff16)
Solutions
- Verify the path exists and is readable: os.Stat / ls -l the ca_cert_path value
- Use an absolute path instead of a relative one, or set the correct working directory
- Fix file permissions so the driver process user can read the cert
- In containers, ensure the cert is mounted/injected before the driver starts
- Clear CACertPath if TLS with a custom CA is not actually needed (falls back to system roots)
Example fix
// before
params.CACertPath = "certs/neo4j-ca.pem" // relative, wrong cwd
// after
if _, err := os.Stat("/etc/neo4j/certs/neo4j-ca.pem"); err != nil {
log.Fatal(err)
}
params.CACertPath = "/etc/neo4j/certs/neo4j-ca.pem" Defensive patterns
Strategy: validation
Validate before calling
// Go: validate the CA cert path before connecting
func validateCACert(path string) error {
if path == "" {
return nil
}
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("CA cert %s: %w", path, err)
}
if info.IsDir() {
return fmt.Errorf("CA cert %s is a directory", path)
}
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("CA cert %s unreadable: %w", path, err)
}
return f.Close()
} Try / catch
cfg, err := neo4jTLSConfigurer(params)
if err != nil {
if strings.Contains(err.Error(), "read Neo4j CA certificate") {
return nil, fmt.Errorf("fix ca_cert_path %q: %w", params.CACertPath, err)
}
return nil, err
} Prevention
- Use absolute cert paths resolved at startup
- Check cert existence/readability in readiness checks before connecting
- In containers, mount certs as read-only volumes and verify after secret injection
- Set explicit file permissions for the driver's service user
When it happens
Trigger: Connecting with a ca_cert_path/connectParams.CACertPath pointing to a file that does not exist, is unreadable by the process user, is a directory, or whose mount is unavailable.
Common situations: Relative path resolved from a different working directory than expected; container image missing the mounted cert; secrets file not yet injected at startup; wrong file permissions after k8s secret mount; typo'd path in the connection config.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Neo4j CA certificate contains no valid PEM certificate
- load Neo4j client certificate: %w
- Hive CA certificate contains no certificates
- both client certificate and client key are required
- ZooKeeper connection event: %w
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/d5a8a3daf1c80ab8.
Report an issue: GitHub.