jaegertracing/jaeger · critical
failed to listen on gRPC port: %w
Error message
failed to listen on gRPC port: %w
What it means
This error is wrapped in Server.Start (cmd/remote-storage/app/server.go:127) when s.grpcCfg.NetAddr.Listen(ctx) fails to bind the configured gRPC network address. Start is called at service start to obtain the net.Listener before grpcServer.Serve runs; a failure here means the process cannot accept gRPC connections on the configured endpoint.
Source
Thrown at cmd/remote-storage/app/server.go:127
)
if err != nil {
return nil, fmt.Errorf("failed to create gRPC server: %w", err)
}
healthServer := health.NewServer()
reflection.Register(server)
v2Handler.Register(server, healthServer)
grpc_health_v1.RegisterHealthServer(server, healthServer)
return server, nil
}
// Start gRPC server concurrently
func (s *Server) Start(ctx context.Context) error {
var err error
s.grpcConn, err = s.grpcCfg.NetAddr.Listen(ctx)
if err != nil {
return fmt.Errorf("failed to listen on gRPC port: %w", err)
}
s.telset.Logger.Info("Starting GRPC server", zap.Stringer("addr", s.grpcConn.Addr()))
s.stopped.Go(func() {
if err := s.grpcServer.Serve(s.grpcConn); err != nil {
s.telset.Logger.Error("GRPC server exited", zap.Error(err))
s.telset.ReportStatus(componentstatus.NewFatalErrorEvent(err))
}
})
return nil
}
// Close stops http, GRPC servers and closes the port listener.
func (s *Server) Close() error {
s.grpcServer.Stop()
s.stopped.Wait()
s.telset.ReportStatus(componentstatus.NewEvent(componentstatus.StatusStopped))
return nilView on GitHub (pinned to 806f444784)
Solutions
- Find what holds the port (lsof -i :<port> or ss -ltnp) and stop it, or change the gRPC NetAddr port in the config
- Use an unprivileged port (>=1024) or grant capabilities (e.g. NET_BIND_SERVICE in Kubernetes) if a privileged port is required
- Correct the NetAddr host:port string; use :0 only if you resolve the actual port via GRPCAddr() after start
- Ensure the context passed to Start is not cancelled/expired before Listen completes
Example fix
// before (config) // grpc: // endpoint: :17271 # already in use by another instance // after // grpc: // endpoint: :17272 # free port, or kill the duplicate process first
Defensive patterns
Strategy: validation
Validate before calling
// before Start, probe the port
addr := s.grpcCfg.NetAddr.Endpoint
ln, err := net.Listen("tcp", addr)
if err != nil {
return fmt.Errorf("gRPC port %s unavailable: %w", addr, err)
}
ln.Close() // let Start bind it for real Try / catch
if err := srv.Start(ctx); err != nil {
if errors.Is(err, syscall.EADDRINUSE) {
log.Fatalf("gRPC endpoint %s already in use; stop the other process or change the port", srv.GRPCAddr())
}
return err
} Prevention
- Use distinct ports per component/instance in shared dev environments; use :0 plus GRPCAddr() for tests
- Add liveness checks (grpc_health_v1) so port conflicts surface immediately
- Clean up stale processes before re-running locally (pkill or docker rm of the prior run)
- Prefer capabilities or unprivileged ports over running as root to bind privileged ports
When it happens
Trigger: Calling Start when the address/port in grpcCfg.NetAddr (e.g. :17271) cannot be bound: port already in use by another process, permission denied on a privileged port (<1024), invalid host/IP in the address, or the context is cancelled before the listener is established.
Common situations: Two remote-storage instances started with the same port; a leftover process from a previous run still holding the port in a dev loop; container port conflicts with a sidecar; typo in the host:port config value.
Related errors
- invalid gRPC server host:port: %w
- query server failed to initialize listener: %w
- could not start jaeger-query: %w
- error creating reader client connection: %w
- error creating writer client connection: %w
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/59c3bc38dc426500.
Report an issue: GitHub.