{"record":{"id":"dd8cebbb01822720","repo":"googleapis/mcp-toolbox","slug":"graceful-shutdown-timed-out-forcing-exit","errorCode":null,"errorMessage":"graceful shutdown timed out... forcing exit","messagePattern":"graceful shutdown timed out\\.\\.\\. forcing exit","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/internal/serve/command.go","lineNumber":133,"sourceCode":"\t\t\t}\n\t\t}()\n\t}\n\n\t// wait for either the server to error out or the command's context to be canceled\n\tselect {\n\tcase err := <-srvErr:\n\t\tif err != nil {\n\t\t\terrMsg := fmt.Errorf(\"toolbox crashed with the following error: %w\", err)\n\t\t\topts.Logger.ErrorContext(ctx, errMsg.Error())\n\t\t\treturn errMsg\n\t\t}\n\tcase <-ctx.Done():\n\t\tshutdownContext, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\t\tdefer cancel()\n\t\topts.Logger.WarnContext(shutdownContext, \"Shutting down gracefully...\")\n\t\terr := s.Shutdown(shutdownContext)\n\t\tif err == context.DeadlineExceeded {\n\t\t\treturn fmt.Errorf(\"graceful shutdown timed out... forcing exit\")\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":115,"sourceCodeEnd":139,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/cmd/internal/serve/command.go#L115-L139","documentation":"On context cancellation runServe attempts a graceful shutdown via s.Shutdown(shutdownContext) with a 10-second timeout. If Shutdown returns context.DeadlineExceeded — in-flight requests/hanging connections prevent completion — this error is returned, signaling a forced exit.","triggerScenarios":"s.Shutdown(shutdownContext) does not complete within the 10-second shutdownContext deadline because long-lived connections (streaming SSE/MCP sessions, websockets, open DB queries) never drain.","commonSituations":"Kubernetes SIGTERM with long-lived MCP streaming connections that don't close, clients keeping keep-alive connections open, or a hung database query blocking drain.","solutions":["Ensure clients close long-lived connections promptly on server shutdown signal","Check for hung database queries/cancellations that block connection cleanup","Increase grace period where the platform allows, or force-close idle connections if the server API exposes it","Log and restart; this is the intended last-resort path and is mostly benign"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := s.Shutdown(shutdownContext)\nif err == context.DeadlineExceeded {\n    // forced exit after grace period — log and proceed\n    logger.Warn(\"graceful shutdown timed out; forcing exit\")\n}","preventionTips":["Keep the default 10s grace period or extend it for streaming workloads","Ensure clients disconnect on SIGTERM (proper MCP/SSE client lifecycle)","Investigate hung DB queries that block connection drain"],"tags":["shutdown","server","timeout","graceful-shutdown"],"backgroundTag":"graceful-shutdown-timeout","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}