jaegertracing/jaeger · error

invalid HTTP server host:port: %w

Error message

invalid HTTP server host:port: %w

What it means

NewServer parses the configured HTTP listener address with net.SplitHostPort before starting servers. If options.HTTP.NetAddr.Endpoint is not a valid host:port (missing port, extra colons, empty string), construction fails with "invalid HTTP server host:port: %w". This is a configuration-time error; the server never starts.

Source

Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/server.go:68

	grpcServer   *grpc.Server
	httpServer   *httpServer
	bgFinished   sync.WaitGroup
	telset       telemetry.Settings
}

// NewServer creates and initializes Server.
func NewServer(
	ctx context.Context,
	querySvc *querysvc.QueryService,
	metricsQuerySvc metricstore.Reader,
	options *QueryOptions,
	backendCaps BackendCapabilityProvider,
	tm *tenancy.Manager,
	telset telemetry.Settings,
) (*Server, error) {
	_, httpPort, err := net.SplitHostPort(options.HTTP.NetAddr.Endpoint)
	if err != nil {
		return nil, fmt.Errorf("invalid HTTP server host:port: %w", err)
	}
	_, grpcPort, err := net.SplitHostPort(options.GRPC.NetAddr.Endpoint)
	if err != nil {
		return nil, fmt.Errorf("invalid gRPC server host:port: %w", err)
	}
	separatePorts := grpcPort != httpPort || grpcPort == "0" || httpPort == "0"

	if (options.HTTP.TLS.HasValue() || options.GRPC.TLS.HasValue()) && !separatePorts {
		return nil, errors.New("server with TLS enabled can not use same host ports for gRPC and HTTP.  Use dedicated HTTP and gRPC host ports instead")
	}

	grpcServer, err := createGRPCServer(ctx, options, tm, telset)
	if err != nil {
		return nil, err
	}
	registerGRPCHandlers(grpcServer, querySvc, telset)
	httpServer, err := createHTTPServer(ctx, querySvc, metricsQuerySvc, options, backendCaps, tm, telset)
	if err != nil {

View on GitHub (pinned to 806f444784)

Solutions

  1. Fix the http.endpoint in the jaeger_query extension config to a valid host:port, e.g. ":16686" or "127.0.0.1:16686".
  2. Wrap IPv6 hosts in brackets: "[::1]:16686".
  3. Verify environment-variable substitutions in the config actually resolve (empty ${VAR} yields an invalid endpoint).
  4. Check the wrapped net.SplitHostPort error for the precise syntax problem.

Example fix

# before
extensions:
  jaeger_query:
    http:
      endpoint: localhost

# after
extensions:
  jaeger_query:
    http:
      endpoint: localhost:16686
Defensive patterns

Strategy: validation

Validate before calling

func validateEndpoint(ep string) error {
    if ep == "" {
        return errors.New("http endpoint is empty")
    }
    _, _, err := net.SplitHostPort(ep)
    return err
}

Type guard

func hasHostPort(ep string) bool {
    _, port, err := net.SplitHostPort(ep)
    return err == nil && port != ""
}

Try / catch

srv, err := NewServer(params, caps, tm, telset)
if err != nil {
    var addrErr *net.AddrError
    if errors.As(err, &addrErr) && strings.Contains(err.Error(), "HTTP server host:port") {
        return fmt.Errorf("check jaeger_query http.endpoint config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: NewServer is called (via serveAndCollect during extension Start, or in tests) with an HTTP endpoint string that net.SplitHostPort rejects: empty endpoint, "://", "host:", "host:port:extra", or an unparseable IPv6 form like "[::1]" without brackets handled properly.

Common situations: Config typo in jaeger_query extension YAML (http.endpoint missing or misspelled), a colon-containing host without brackets for IPv6, an empty string from an environment variable substitution that did not resolve, or port omitted entirely.

Related errors


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