jaegertracing/jaeger · warning
failed to close HTTP server: %w
Error message
failed to close HTTP server: %w
What it means
Server.Close shuts down the HTTP server, stops the gRPC server, and waits for background work, collecting any errors into a joined error. If httpServer.Close() returns non-nil — e.g. the underlying listener is already closed or in a bad state — it is wrapped as 'failed to close HTTP server' and combined with any other shutdown errors.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/server.go:512
})
return nil
}
func (s *Server) HTTPAddr() string {
return s.httpConn.Addr().String()
}
func (s *Server) GRPCAddr() string {
return s.grpcConn.Addr().String()
}
// Close stops HTTP, GRPC servers and closes the port listener.
func (s *Server) Close() error {
var errs []error
s.telset.Logger.Info("Closing HTTP server")
if err := s.httpServer.Close(); err != nil {
errs = append(errs, fmt.Errorf("failed to close HTTP server: %w", err))
}
s.telset.Logger.Info("Stopping gRPC server")
s.grpcServer.Stop()
s.bgFinished.Wait()
s.telset.Logger.Info("Server stopped")
return errors.Join(errs...)
}
View on GitHub (pinned to 806f444784)
Solutions
- Inspect the wrapped inner error: if it indicates the server is already closed, ensure Close is called exactly once (guard with sync.Once)
- Check for hijacked/streaming connections (e.g. WebSocket upgrades through the proxy) and close/complete them before shutdown
- Log and treat the remaining errors as non-fatal during shutdown — the joined error still reports all sub-system failures
Example fix
var closeOnce sync.Once
// before: Close may be called twice and fail on the second call
close(s.httpServer)
// after
closeOnce.Do(func() { _ = server.Close() }) Defensive patterns
Strategy: try-catch
Try / catch
if err := server.Close(); err != nil {
// inspect joined sub-errors individually
for _, e := range errors.Unwrap(err).([]error) {
log.Warn("shutdown sub-error", zap.Error(e))
}
} Prevention
- Call Close exactly once per server instance (sync.Once guard) to avoid double-close errors
- Drain or complete hijacked/streaming connections (WebSockets) before Close
- Treat shutdown errors as warnings — log them but do not block process exit
When it happens
Trigger: Calling Server.Close() (extension shutdown / SIGTERM path) when http.Server.Close() fails, which practically only happens if the server was already closed, its listener was force-closed, or an in-flight hijacked connection causes an error return from the stdlib.
Common situations: Double-invocation of Close (e.g. graceful-shutdown hook plus extension teardown both calling it); a listener hijacked by a streaming/upgrade connection resisting the abrupt close; process shutdown racing with the health-check or OTLP proxy connections.
Related errors
- access denied
- no http.RoundTripper provided
- bad request
- abnormal value of http status code: %v
- %s and %s are required
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/5c6be4e3f94a0a4f.
Report an issue: GitHub.