From f4f32121a602ef0e0187345fb8e298ed3b3fa347 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 5 Nov 2025 17:08:29 +0000 Subject: [PATCH] Fix vMCP server graceful shutdown Resolves shutdown hang and "use of closed network connection" errors by: removing redundant listener.Close() call since httpServer.Shutdown() already handles listener cleanup internally. Previously you would have seen: ``` 5:21PM ERROR Errors during shutdown: [failed to close listener: close tcp 127.0.0.1:4483: use of closed network connection] Error: failed to close listener: close tcp 127.0.0.1:4483: use of closed network connection 5:21PM ERROR Error executing command: failed to close listener: close tcp 127.0.0.1:4483: use of closed network connection ``` --- pkg/vmcp/server/server.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/pkg/vmcp/server/server.go b/pkg/vmcp/server/server.go index 0074cb841..ce130156c 100644 --- a/pkg/vmcp/server/server.go +++ b/pkg/vmcp/server/server.go @@ -309,7 +309,7 @@ func (s *Server) Stop(ctx context.Context) error { var errs []error - // Stop HTTP server + // Stop HTTP server (this internally closes the listener) if s.httpServer != nil { // Create shutdown context with timeout shutdownCtx, cancel := context.WithTimeout(ctx, defaultShutdownTimeout) @@ -320,19 +320,12 @@ func (s *Server) Stop(ctx context.Context) error { } } - // Close listener + // Clear listener reference (already closed by httpServer.Shutdown) s.listenerMu.Lock() - listener := s.listener s.listener = nil s.listenerMu.Unlock() - if listener != nil { - if err := listener.Close(); err != nil { - errs = append(errs, fmt.Errorf("failed to close listener: %w", err)) - } - } - - // Stop session manager + // Stop session manager after HTTP server shutdown if s.sessionManager != nil { if err := s.sessionManager.Stop(); err != nil { errs = append(errs, fmt.Errorf("failed to stop session manager: %w", err))