yudai/gotty · error

could not open CA crt file %s

Error message

could not open CA crt file %s

What it means

tlsConfig() expands TLSCACrtFile with homedir.Expand and reads it with ioutil.ReadFile. If the read fails (missing file, bad path, permissions), it returns this plain error containing the expanded path. Note the homedir.Expand error itself is ignored, so '~' that cannot be expanded silently yields a literal '~...' path.

Source

Thrown at server/server.go:235

		Handler: handler,
	}

	if server.options.EnableTLSClientAuth {
		tlsConfig, err := server.tlsConfig()
		if err != nil {
			return nil, errors.Wrapf(err, "failed to setup TLS configuration")
		}
		srv.TLSConfig = tlsConfig
	}

	return srv, nil
}

func (server *Server) tlsConfig() (*tls.Config, error) {
	caFile := homedir.Expand(server.options.TLSCACrtFile)
	caCert, err := ioutil.ReadFile(caFile)
	if err != nil {
		return nil, errors.New("could not open CA crt file " + caFile)
	}
	caCertPool := x509.NewCertPool()
	if !caCertPool.AppendCertsFromPEM(caCert) {
		return nil, errors.New("could not parse CA crt file data in " + caFile)
	}
	tlsConfig := &tls.Config{
		ClientCAs:  caCertPool,
		ClientAuth: tls.RequireAndVerifyClientCert,
	}
	return tlsConfig, nil
}

View on GitHub (pinned to a080c85cbc)

Solutions

  1. Check the path in the error message exists: ls -l <path>
  2. Fix tls_ca_crt_file in your config/flags to the real CA bundle path
  3. Verify file permissions for the user running GoTTY
  4. If using '~', ensure HOME is set for the process

Example fix

// before
tls_ca_crt_file = "~/ca.crt"  # HOME unset in systemd unit
// after
tls_ca_crt_file = "/home/gotty/ca.crt"
Defensive patterns

Strategy: validation

Validate before calling

caPath := expandHome(opts.TLSCACrtFile)
if fi, err := os.Stat(caPath); err != nil || fi.IsDir() {
    log.Fatalf("CA file %q not accessible", caPath)
}

Try / catch

if err := srv.Run(ctx); err != nil {
    if strings.Contains(err.Error(), "could not open CA crt file") {
        log.Fatalf("CA file missing: %v", err)
    }
}

Prevention

When it happens

Trigger: Calling Run() with EnableTLSClientAuth=true when TLSCACrtFile does not exist, is a directory, or is not readable by the current user.

Common situations: Typo in the cert path; '~' not expanding when running under a service account with no HOME; cert never provisioned in a container image.

Related errors


AI-assisted analysis of yudai/gotty@a080c85cbc (2026-09-02). Data as JSON: /api/errors/7ab858324b7cc004. Report an issue: GitHub.