jaegertracing/jaeger · error

failed to parse admin server TLS options: %w

Error message

failed to parse admin server TLS options: %w

What it means

AdminServer.initFromViper parses the admin HTTP server's TLS flags (tlsAdminHTTPFlagsConfig.InitFromViper). If those TLS options are invalid — bad cert/key file references, malformed values — the error is wrapped as "failed to parse admin server TLS options". It occurs before the admin server starts, so the whole service fails to boot.

Source

Thrown at cmd/internal/flags/admin.go:85

// setLogger initializes logger.
func (s *AdminServer) setLogger(logger *zap.Logger) {
	s.logger = logger
}

// AddFlags registers CLI flags.
func (s *AdminServer) AddFlags(flagSet *flag.FlagSet) {
	flagSet.String(adminHTTPHostPort, s.serverCfg.NetAddr.Endpoint, fmt.Sprintf("The host:port (e.g. 127.0.0.1%s or %s) for the admin server, including health check, /metrics, etc.", s.serverCfg.NetAddr.Endpoint, s.serverCfg.NetAddr.Endpoint))
	tlsAdminHTTPFlagsConfig.AddFlags(flagSet)
}

// InitFromViper initializes the server with properties retrieved from Viper.
func (s *AdminServer) initFromViper(v *viper.Viper, logger *zap.Logger) error {
	s.setLogger(logger)

	tlsAdminHTTP, err := tlsAdminHTTPFlagsConfig.InitFromViper(v)
	if err != nil {
		return fmt.Errorf("failed to parse admin server TLS options: %w", err)
	}

	s.serverCfg.NetAddr.Endpoint = v.GetString(adminHTTPHostPort)
	s.serverCfg.TLS = tlsAdminHTTP
	return nil
}

// Handle adds a new handler to the admin server.
func (s *AdminServer) Handle(path string, handler http.Handler) {
	s.mux.Handle(path, handler)
}

// Serve starts HTTP server.
func (s *AdminServer) Serve() error {
	l, err := s.serverCfg.ToListener(context.Background())
	if err != nil {
		s.logger.Error("Admin server failed to listen", zap.Error(err))
		return err

View on GitHub (pinned to 806f444784)

Solutions

  1. Check the wrapped cause: it names the invalid TLS field or unreadable file.
  2. Verify cert/key file paths exist and are readable inside the container.
  3. If TLS is not needed, remove the TLS flags or set --admin.http.tls.enabled=false.
  4. Align the secret mount names/paths in the deployment with the flags.

Example fix

// before
--admin.http.tls.enabled=true --admin.http.tls.cert=/missing/tls.crt
// after
--admin.http.tls.enabled=true --admin.http.tls.cert=/etc/jaeger/tls/tls.crt --admin.http.tls.key=/etc/jaeger/tls/tls.key
Defensive patterns

Strategy: validation

Validate before calling

if tlsCfg.Enabled {
    for _, p := range []string{tlsCfg.CertPath, tlsCfg.KeyPath} {
        if _, err := os.Stat(p); err != nil {
            return fmt.Errorf("TLS file missing: %s", p)
        }
    }
}

Try / catch

if err := svc.Start(viper); err != nil {
    if strings.Contains(err.Error(), "admin server TLS options") {
        // inspect --admin.http.tls.* flags
    }
    log.Fatal(err)
}

Prevention

When it happens

Trigger: Setting --admin.http.tls.enabled=true without providing a certificate/key, pointing to nonexistent cert/key files, or supplying malformed TLS flag values that the tls config parser rejects.

Common situations: Mount not present in the pod so cert paths are empty; enabled TLS with self-signed cert paths typed incorrectly; user disables TLS but leaves stale cert flags that fail validation; typo in flag name.

Understand the failure class

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/1b3b1a1e5e7a57c1. Report an issue: GitHub.