jaegertracing/jaeger · error

cannot start the admin server: %w

Error message

cannot start the admin server: %w

What it means

This error wraps a failure from s.Admin.Serve(), which binds and starts the admin HTTP server during flags.Start(). Serve opens the configured host:port and serves health-check and metrics routes; if the listener cannot be created or served, Jaeger returns this error instead of continuing to run the main service.

Source

Thrown at cmd/internal/flags/service.go:105

	s.MetricsFactory = metricsFactory

	if err = s.Admin.initFromViper(v, s.Logger); err != nil {
		return fmt.Errorf("cannot initialize admin server: %w", err)
	}
	if h := metricsBuilder.Handler(); h != nil {
		route := metricsBuilder.HTTPRoute
		s.Logger.Info("Mounting metrics handler on admin server", zap.String("route", route))
		s.Admin.Handle(route, h)
	}

	// Mount expvar routes on different backends
	if metricsBuilder.Backend != "expvar" {
		s.Logger.Info("Mounting expvar handler on admin server", zap.String("route", "/debug/vars"))
		s.Admin.Handle("/debug/vars", expvar.Handler())
	}

	if err := s.Admin.Serve(); err != nil {
		return fmt.Errorf("cannot start the admin server: %w", err)
	}

	return nil
}

// RunAndThen sets the health check to Ready and blocks until SIGTERM is received.
// It then runs the shutdown function and exits.
func (s *Service) RunAndThen(shutdown func()) error {
	s.Admin.Host().Ready()

	<-s.signalsChannel

	s.Logger.Info("Shutting down")
	s.Admin.Host().SetUnavailable()

	if shutdown != nil {
		shutdown()
	}

View on GitHub (pinned to 806f444784)

Solutions

  1. Free port 14269 (or your configured jaeger.admin.http.host-port): kill the process holding it, e.g. `lsof -i :14269` then stop that process
  2. Change jaeger.admin.http.host-port in the config to a free port
  3. Run as a user allowed to bind the port, or use an unprivileged port (>1024)
  4. Read the wrapped `%w` cause — it will typically say `address already in use` or `permission denied`

Example fix

// before (config.yaml)
jaeger:
  admin:
    http:
      host-port: ":14269"  # already in use
// after
jaeger:
  admin:
    http:
      host-port: ":14270"
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the admin port is free before starting
addr := v.GetString("jaeger.admin.http.host-port")
if addr == "" { addr = ":14269" }
if ln, err := net.Listen("tcp", addr); err != nil {
    return fmt.Errorf("admin port %s unavailable: %w", addr, err)
} else {
    ln.Close()
}

Try / catch

if err := svc.Start(v); err != nil {
    var oe *net.OpError
    if errors.As(err, &oe) && errors.Is(oe.Err, syscall.EADDRINUSE) {
        log.Fatalf("admin port in use; free it or change jaeger.admin.http.host-port: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling flags.Start() when the admin port is already bound by another process, the host:port is unbindable (privileged port without permission, invalid host), or the listener closes with an error other than http.ErrServerClosed during startup.

Common situations: Two Jaeger instances on the same host both using default admin port 14269; a leftover process holding the port; running in a container with a port already published; host-port configured to a privileged port as non-root.

Related errors


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