gofr-dev/gofr · error
failed to read CA certificate from %s: %w
Error message
failed to read CA certificate from %s: %w
What it means
Raised in registerMySQLTLSConfig when os.ReadFile fails on the DB_TLS_CA_CERT_PATH configured for MySQL TLS. The wrapped os error tells you whether the file is missing, permission-denied, or is a directory. gofr cannot build the custom TLS config without the CA material.
Source
Thrown at pkg/gofr/datasource/sql/sql.go:517
}
caCertPath := os.Getenv("DB_TLS_CA_CERT")
if caCertPath == "" {
logger.Warn("DB_SSL_MODE=verify-ca requires DB_TLS_CA_CERT. Falling back to system CA pool")
// Use system CA pool
tlsConfig := &tls.Config{
ServerName: getServerName(dbConfig.HostName),
MinVersion: tls.VersionTLS12,
}
return mysql.RegisterTLSConfig("custom", tlsConfig)
}
// Load custom CA certificate
caCert, err := os.ReadFile(caCertPath) //nolint:gosec // caCertPath is an operator-supplied configuration path, not user input
if err != nil {
return fmt.Errorf("failed to read CA certificate from %s: %w", caCertPath, err)
}
caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM(caCert) {
return errFailedCACerts
}
tlsConfig := &tls.Config{
RootCAs: caCertPool,
ServerName: dbConfig.HostName,
MinVersion: tls.VersionTLS12,
}
// Optional: Support client certificates (mutual TLS)
clientCertPath := os.Getenv("DB_TLS_CLIENT_CERT")
clientKeyPath := os.Getenv("DB_TLS_CLIENT_KEY")
if clientCertPath != "" && clientKeyPath != "" {View on GitHub (pinned to 187eb24962)
Solutions
- Verify the file exists at DB_TLS_CA_CERT_PATH (ls -l the path inside the container).
- Fix file permissions so the process user can read the cert (chmod 644 / correct secret mount mode).
- Use an absolute path; confirm the container volume/secret is mounted.
- Correct any typo in the DB_TLS_CA_CERT_PATH environment variable.
Example fix
// before DB_TLS_CA_CERT_PATH=/etc/ssl/certs/ca.pem (file not mounted) // after docker run -v ./certs/ca.pem:/etc/ssl/certs/ca.pem:ro ... DB_TLS_CA_CERT_PATH=/etc/ssl/certs/ca.pem
Defensive patterns
Strategy: validation
Validate before calling
path := os.Getenv("DB_TLS_CA_CERT_PATH")
if path != "" {
if fi, err := os.Stat(path); err != nil || fi.IsDir() {
return fmt.Errorf("CA cert path %q unreadable", path)
}
} Prevention
- Use absolute paths for cert files in containers.
- Assert secret mounts exist in entrypoint/startup scripts.
- Run containers with the cert directory mounted read-only and correct ownership.
When it happens
Trigger: NewSQL (mysql dialect) with DB_TLS_CA_CERT_PATH set to a nonexistent path, a path in an unmounted volume, or a file the process user cannot read (permission denied).
Common situations: Typo in the cert path env var, secret not mounted into the container, running the container as a non-root user without read access, or relative path used where a working directory differs.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to append CA certificate
- failed to load client certificate: %w
- invalid certificate file
- invalid key file
- %w : %v
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/75a0e34dce4ae495.
Report an issue: GitHub.