Skip to content

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

Description

@RaviTharuma

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.

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