yudai/gotty · error

failed to setup TLS configuration

Error message

failed to setup TLS configuration

What it means

setupHTTPServer() constructs the http.Server; when EnableTLSClientAuth is enabled it also builds a tls.Config via server.tlsConfig(). Any failure there is wrapped with this message and propagates to Run() (which wraps it again as 'failed to setup an HTTP server').

Solutions

  1. Inspect the wrapped inner error for the exact cause
  2. Ensure tls_ca_crt_file points to an existing PEM-encoded CA certificate
  3. Disable enable_tls_client_auth if mTLS is not required

Example fix

// before
tls_ca_crt_file = ""
enable_tls_client_auth = true
// after
tls_ca_crt_file = "/etc/gotty/ca.crt"
enable_tls_client_auth = true
Defensive patterns

Strategy: validation

Validate before calling

if opts.EnableTLSClientAuth && opts.TLSCACrtFile == "" {
    log.Fatal("enable_tls_client_auth requires tls_ca_crt_file")
}

Try / catch

if err := srv.Run(ctx); err != nil {
    if strings.Contains(err.Error(), "failed to setup TLS configuration") {
        log.Fatalf("TLS setup: %v", err)
    }
}

Prevention

When it happens

Trigger: Calling Run() with EnableTLSClientAuth=true while tlsConfig() fails — CA cert file unreadable (error 14) or unparseable (error 15).

Common situations: Mutual-TLS setups where tls_ca_crt_file is unset (expands to a bad default path) or points to a leaf cert/invalid PEM instead of a CA.

Understand the failure class

Related errors


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

Appendix: source

Thrown at server/server.go:223

	siteHandler = server.wrapLogger(withGz)

	wsMux := http.NewServeMux()
	wsMux.Handle("/", siteHandler)
	wsMux.HandleFunc(pathPrefix+"ws", server.generateHandleWS(ctx, cancel, counter))
	siteHandler = http.Handler(wsMux)

	return siteHandler
}

func (server *Server) setupHTTPServer(handler http.Handler) (*http.Server, error) {
	srv := &http.Server{
		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{

View on GitHub (pinned to a080c85cbc)