jaegertracing/jaeger · error

invalid gRPC server host:port: %w

Error message

invalid gRPC server host:port: %w

What it means

NewServer likewise validates the gRPC listener address with net.SplitHostPort. If options.GRPC.NetAddr.Endpoint is not a valid host:port, construction fails with "invalid gRPC server host:port: %w". Like the HTTP variant it is a fail-fast configuration error before any listener is created.

Source

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

}

// 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 {
		return nil, err
	}

	return &Server{

View on GitHub (pinned to 806f444784)

Solutions

  1. Fix grpc.endpoint to a valid host:port, e.g. ":16685" or "127.0.0.1:16685".
  2. Bracket IPv6 hosts: "[::1]:16685".
  3. Ensure ${ENV} substitutions used in the endpoint resolve to non-empty values.
  4. Check the wrapped net.SplitHostPort error for the exact syntax issue; also confirm the HTTP variant (error 213) passes if using a shared port.

Example fix

# before
extensions:
  jaeger_query:
    grpc:
      endpoint: ${JAEGER_GRPC}
# (JAEGER_GRPC unset -> empty endpoint)

# after
extensions:
  jaeger_query:
    grpc:
      endpoint: 127.0.0.1:16685
Defensive patterns

Strategy: validation

Validate before calling

func validateGRPCEndpoint(ep string) error {
    if ep == "" {
        return errors.New("grpc endpoint is empty")
    }
    if strings.Contains(ep, "://") {
        return errors.New("grpc endpoint must be host:port, not a URL")
    }
    _, _, 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(), "gRPC server host:port") {
        return fmt.Errorf("check jaeger_query grpc.endpoint config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: NewServer (via serveAndCollect or tests) receives a gRPC endpoint net.SplitHostPort cannot parse: empty string, bare host with no port, multiple colons, or malformed IPv6 literal without brackets.

Common situations: grpc.endpoint omitted or left empty in the jaeger_query extension config, environment variable substitution producing an empty value, IPv6 address written unbracketed, or accidental paste of a URL ("http://host:port") into the endpoint field.

Related errors


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