googleapis/mcp-toolbox · warning

graceful shutdown timed out... forcing exit

Error message

graceful shutdown timed out... forcing exit

What it means

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.

Source

Thrown at cmd/internal/serve/command.go:133

			}
		}()
	}

	// wait for either the server to error out or the command's context to be canceled
	select {
	case err := <-srvErr:
		if err != nil {
			errMsg := fmt.Errorf("toolbox crashed with the following error: %w", err)
			opts.Logger.ErrorContext(ctx, errMsg.Error())
			return errMsg
		}
	case <-ctx.Done():
		shutdownContext, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()
		opts.Logger.WarnContext(shutdownContext, "Shutting down gracefully...")
		err := s.Shutdown(shutdownContext)
		if err == context.DeadlineExceeded {
			return fmt.Errorf("graceful shutdown timed out... forcing exit")
		}
	}

	return nil
}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Ensure clients close long-lived connections promptly on server shutdown signal
  2. Check for hung database queries/cancellations that block connection cleanup
  3. Increase grace period where the platform allows, or force-close idle connections if the server API exposes it
  4. Log and restart; this is the intended last-resort path and is mostly benign
Defensive patterns

Strategy: retry

Try / catch

err := s.Shutdown(shutdownContext)
if err == context.DeadlineExceeded {
    // forced exit after grace period — log and proceed
    logger.Warn("graceful shutdown timed out; forcing exit")
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/dd8cebbb01822720. Report an issue: GitHub.