hasura/graphql-engine · error

error reading CA %s: %w

Error message

error reading CA %s: %w

What it means

Thrown by httpc.GenerateTLSConfig when the CA file configured for the client cannot be read from disk. The underlying os.ReadFile error is wrapped with the CA path, so the message shows both the configured path and the OS-level cause (no such file, permission denied, etc.).

Source

Thrown at cli/internal/httpc/httpc.go:198

}

func GenerateTLSConfig(caPath string, insecureSkipTLSVerify bool) (*tls.Config, error) {
	var op errors.Op = "httpc.GenerateTLSConfig"

	tlsConfig := &tls.Config{InsecureSkipVerify: insecureSkipTLSVerify}

	if caPath != "" {
		// Get the SystemCertPool, continue with an empty pool on error
		rootCAs, _ := x509.SystemCertPool()
		if rootCAs == nil {
			rootCAs = x509.NewCertPool()
		}
		// read cert
		certPath, _ := filepath.Abs(caPath)

		cert, err := os.ReadFile(certPath)
		if err != nil {
			return nil, errors.E(op, fmt.Errorf("error reading CA %s: %w", caPath, err))
		}

		if ok := rootCAs.AppendCertsFromPEM(cert); !ok {
			return nil, errors.E(op, stderrors.New("unable to append given CA cert"))
		}

		tlsConfig.RootCAs = rootCAs
	}

	return tlsConfig, nil
}

func NewHttpClientWithTLSConfig(tlsConfig *tls.Config) (*http.Client, error) {
	tr := &http.Transport{TLSClientConfig: tlsConfig}
	tr.Proxy = http.ProxyFromEnvironment
	httpClient := &http.Client{Transport: tr}

	return httpClient, nil

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check the exact path in the error and verify the file exists at that absolute location
  2. Use an absolute path for the CA cert, or run the CLI from the directory the relative path resolves from
  3. Fix permissions: chmod 644 <ca.pem> and ensure the running user can read it
  4. If the server uses a public CA, remove the CA config entirely

Example fix

# before
ca_cert: ./certs/ca.pem   # run from another dir -> ENOENT

# after
ca_cert: /home/me/project/certs/ca.pem
Defensive patterns

Strategy: validation

Validate before calling

if c.CAPath != "" {
	abs, err := filepath.Abs(c.CAPath)
	if err != nil { log.Fatal(err) }
	if fi, err := os.Stat(abs); err != nil || fi.IsDir() {
		log.Fatalf("CA cert missing or unreadable: %s", abs)
	}
}

Try / catch

cfg, err := httpc.GenerateTLSConfig(...)
if err != nil {
	if strings.Contains(err.Error(), "error reading CA") {
		// fix the CA path in config before retrying; not retryable as-is
	}
	return err
}

Prevention

When it happens

Trigger: Setting a CA path in the CLI config (e.g. ca_cert in config.yaml or --ca-certificate flag) that does not exist, is a directory, has restrictive permissions, or is relative to a different working directory (it's resolved with filepath.Abs against the process CWD).

Common situations: Relative CA paths breaking when the CLI is run from another directory, wrong path after moving a project, expired cert files cleaned up, or file permissions blocking read access (common in CI containers running as a different user).

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/c854a1f2bf80ba75. Report an issue: GitHub.