nats-io/nats-server · error

TLS cert and key required for HTTPS

Error message

TLS cert and key required for HTTPS

What it means

Monitoring was configured on HTTPS (`https_port`) but the options carry no TLS configuration. An HTTPS monitor endpoint requires a certificate and key via tls config; StartMonitoring rejects this misconfiguration at startup.

Source

Thrown at server/server.go:3036

func (s *Server) StartHTTPSMonitoring() {
	s.startMonitoring(true)
}

// StartMonitoring starts the HTTP or HTTPs server if needed.
func (s *Server) StartMonitoring() error {
	// Snapshot server options.
	opts := s.getOpts()

	// Specifying both HTTP and HTTPS ports is a misconfiguration
	if opts.HTTPPort != 0 && opts.HTTPSPort != 0 {
		return fmt.Errorf("can't specify both HTTP (%v) and HTTPs (%v) ports", opts.HTTPPort, opts.HTTPSPort)
	}
	var err error
	if opts.HTTPPort != 0 {
		err = s.startMonitoring(false)
	} else if opts.HTTPSPort != 0 {
		if opts.TLSConfig == nil {
			return fmt.Errorf("TLS cert and key required for HTTPS")
		}
		err = s.startMonitoring(true)
	}
	return err
}

// HTTP endpoints
const (
	RootPath         = "/"
	VarzPath         = "/varz"
	ConnzPath        = "/connz"
	RoutezPath       = "/routez"
	GatewayzPath     = "/gatewayz"
	LeafzPath        = "/leafz"
	SubszPath        = "/subsz"
	StackszPath      = "/stacksz"
	AccountzPath     = "/accountz"
	AccountStatzPath = "/accstatz"

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Add a `tls` block with cert/key (and ca if needed) to the server config alongside https_port
  2. Or use plain `http_port` if TLS is not required
  3. Ensure the TLS block is at the right level so it populates opts.TLSConfig

Example fix

// before
https_port: 8222
// after
https_port: 8222
tls {
  cert: "./certs/server-cert.pem"
  key: "./certs/server-key.pem"
}
Defensive patterns

Strategy: validation

Validate before calling

// Before Start(): https_port requires a TLS config with cert+key
if opts.HTTPSPort != 0 {
    if opts.TLSConfig == nil || len(opts.TLSConfig.Certificates) == 0 {
        return errors.New("https_port set but no TLS cert/key configured")
    }
}

Try / catch

if err := srv.StartMonitoring(); err != nil {
    if strings.Contains(err.Error(), "TLS cert and key required") {
        log.Print("add a tls{cert,key} block or switch to http_port")
    }
    return err
}

Prevention

When it happens

Trigger: Config sets `https_port` but no `tls { cert, key }` block, so opts.TLSConfig == nil when StartMonitoring runs.

Common situations: Copying an HTTP-port config and renaming the field to https_port without adding TLS; assuming monitoring TLS is configured separately from client TLS; missing cert files commented out.

Understand the failure class

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/8b7194c39d20bf11. Report an issue: GitHub.