{"record":{"id":"cb49f99d0a1c4759","repo":"jaegertracing/jaeger","slug":"could-not-start-jaeger-query-w","errorCode":null,"errorMessage":"could not start jaeger-query: %w","messagePattern":"could not start jaeger-query: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/server.go","lineNumber":148,"sourceCode":"\t\t}\n\t}\n\n\ts.server, err = queryapp.NewServer(\n\t\tctx,\n\t\t// TODO propagate healthcheck updates up to the collector's runtime\n\t\tqs,\n\t\tmqs,\n\t\t&s.config.QueryOptions,\n\t\tbackendCaps,\n\t\ttm,\n\t\ttelset,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not create jaeger-query: %w\", err)\n\t}\n\n\tif err := s.server.Start(ctx); err != nil {\n\t\treturn fmt.Errorf(\"could not start jaeger-query: %w\", err)\n\t}\n\n\t// Start the health checker only after the query server is up — a failed\n\t// server start (e.g. port bind error) returns an error from Start, and\n\t// the OTel collector does not call Shutdown in that case. Starting the\n\t// checker first would leak its goroutine forever. The checker is given a\n\t// fresh background context because the Start context is cancelled when\n\t// Start returns; Shutdown stops the checker explicitly.\n\tif s.aiHealth != nil {\n\t\ts.aiHealth.Start(context.Background()) //nolint:contextcheck // intentional: checker outlives Start ctx; Shutdown stops it.\n\t}\n\n\treturn nil\n}\n\n// buildAIHealthChecker constructs an AI health checker when the operator opted in\n// (jaeger_query.ai block present with a non-empty agent URL and a positive\n// check interval). Returns nil when AI is disabled — there's nothing to","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/server.go#L130-L166","documentation":"queryapp.NewServer succeeded but s.server.Start(ctx) failed while binding/starting the HTTP and gRPC listeners. The failure (most commonly a port bind error) is wrapped as 'could not start jaeger-query'.","triggerScenarios":"Another process already holds the configured HTTP (default 16686) or gRPC (16685) port; insufficient privileges for the port; listener creation or TLS setup fails at bind time.","commonSituations":"Running two jaeger-query instances on one host; port already used by another collector extension; running in a container where the port is occupied by a sidecar; permission denied on privileged ports (<1024).","solutions":["Check which process holds the port (ss -ltnp / lsof) and stop it or change the endpoint port","Change jaeger_query http/grpc endpoint ports in the config","Ensure the container/pod has the port mapped/free and the process has bind permission","Check logs for which listener (HTTP vs gRPC) failed to bind"],"exampleFix":"// before\njaeger_query:\n  http:\n    endpoint: \":16686\"  # already in use\n// after\njaeger_query:\n  http:\n    endpoint: \":16687\"","handlingStrategy":"try-catch","validationCode":"// Check port availability before starting\nfor _, port := range []string{\":16686\", \":16685\"} {\n\tln, err := net.Listen(\"tcp\", port)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"port %s in use\", port)\n\t}\n\tln.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := ext.Start(ctx, host); err != nil {\n\tvar opErr *net.OpError\n\tif errors.As(err, &opErr) && strings.Contains(opErr.Error(), \"address already in use\") {\n\t\tlog.Fatalf(\"query port busy: %v — free the port or change the endpoint\", err)\n\t}\n\treturn err\n}","preventionTips":["Run one jaeger-query instance per host/pod per port set","Prefer :0 or explicit unique ports in multi-tenant environments","Verify no other collector extensions claim the same ports","Use non-privileged ports or grant bind capabilities"],"tags":["go","network","port-bind","startup"],"backgroundTag":"address-already-in-use","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}