Skip to content

bug(operator): kubectl rollout restart of ToolHive workloads is reverted; no supported bounce API #6344

Description

@RaviTharuma

Status

Fix PR: #6378


Bug description

There is no supported way to bounce a ToolHive-managed MCP workload.

  • kubectl rollout restart deploy/<name> / sts/<name> is reverted by the operator within about a second (it treats the restart annotation / template hash as drift).
  • Patching StatefulSet replicas is also reverted ([BUG] Operator reverts manual StatefulSet replica scaling back to 1 #3329, closed as “operator is source of truth”).
  • The documented-looking kubectl rollout restart path therefore does nothing useful.

The only thing that actually recycles a pod is kubectl delete pod -l toolhive-name=<name>. That is not documented, and for stdio servers you have to know which pod is the proxy vs the workload.

This matters for the known vMCP memory growth (#5860): the practical mitigation is a nightly pod delete, not a rollout.

Steps to reproduce

  1. Deploy any MCPServer or VirtualMCPServer on the operator.
  2. kubectl rollout restart deploy/<name> -n <ns>
  3. Immediately kubectl get deploy <name> -n <ns> -o yaml | grep restartedAt (or watch ReplicaSets).

Expected behavior

Either:

  • honor kubectl rollout restart (ignore kubectl.kubernetes.io/restartedAt in the drift check, or re-apply it), or
  • document a first-class bounce: annotation on the CR (toolhive.stacklok.dev/restartedAt), kubectl annotate mcpserver …, or a condition the operator turns into a new ReplicaSet.

Actual behavior

Operator writes the Deployment/StatefulSet spec back to the desired template and the restart is gone. Users conclude “rollout restart is the runbook” and then wonder why memory/leak mitigations never fire.

Environment (if relevant)

  • OS/version: Talos Linux, Kubernetes
  • ToolHive version: operator v0.43.0 (behavior also seen on earlier 0.3x)

Additional context

Related: #3329 (replica scale-back). #5860 (vMCP leak — current workaround is kubectl delete pod -l toolhive-name=…, because rollout restart is a no-op).

Happy to take a docs-only fix if product intent is “never mutate child workloads”; then the CR annotation / thv command needs to exist so GitOps and CronJobs have something legal to do.

No credentials or private hostnames in this report.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIssue needs initial triage by a maintainer

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions