#13984·calico

kube-controllers still logs `unknown field "status"` every 10s on v3.32.2 — from EnsureInitialized/ensureTierExists, not the tier controller

Author: acimCreated Sep 18, 2026Updated Sep 21, 2026
Labelskind/support

Expected Behavior

calico-kube-controllers should not log Warning: unknown field "status" on a healthy, idle cluster.

Current Behavior

On Calico v3.32.2 (which includes #13446, the backport of #13082), calico-kube-controllers still logs the warning three times every 10 seconds:

I0917 20:44:13.515488      14 warnings.go:107] "Warning: unknown field \"status\""
I0917 20:44:13.521455      14 warnings.go:107] "Warning: unknown field \"status\""
I0917 20:44:13.527569      14 warnings.go:107] "Warning: unknown field \"status\""
I0917 20:44:23.544956      14 warnings.go:107] "Warning: unknown field \"status\""
I0917 20:44:23.552988      14 warnings.go:107] "Warning: unknown field \"status\""
I0917 20:44:23.564985      14 warnings.go:107] "Warning: unknown field \"status\""

~26k lines per day. Related to #13079, where this was attributed to the tier controller's finalizer Update. That path is fixed in v3.32.2 (tier_controller.go now uses Patch), but the warning comes from a second code path that #13082 did not cover.

Possible Solution

The source is the kube-controllers health-check loop:

  • kube-controllers/cmd/kube-controllers/main.gorunHealthChecks() calls calicoClient.EnsureInitialized(healthCtx, "", "k8s") every 10 s (line 278 at v3.32.2).
  • libcalico-go/lib/clientv3/client.goEnsureInitialized() calls ensureTierExists() for default, kube-admin and kube-baseline (lines 298–310), which unconditionally does c.Tiers().Create(...) and swallows ErrorResourceAlreadyExists (line 460+).
  • api/pkg/apis/projectcalico/v3/tier.go:44Status TierStatus \json:"status,omitempty"`is a non-pointer struct, soomitemptyhas no effect and everyCreatebody carries"status":{}`. The apiserver flags the field (it belongs to the status subresource) before rejecting the create with AlreadyExists.

Three tiers × one Create each × every 10 s = exactly the observed rate. The same code is still on master.

Options:

  1. Make Tier.Status a pointer (*TierStatus) so omitempty actually omits it — same shape of fix as #13082's motivation.
  2. In ensureTierExists, Get() first and only Create() when not found (also avoids three pointless write requests per health check).
  3. Strip Status from the object before Create in ensureTierExists.

Steps to Reproduce (for bugs)

  1. Install Calico v3.32.2 via tigera-operator on Kubernetes 1.35 (default aggregated-apiserver mode).
  2. kubectl -n calico-system logs deploy/calico-kube-controllers | grep 'unknown field'
  3. Observe three warnings every 10 s.

Context

Purely cosmetic — nothing misbehaves — but it makes the kube-controllers log unusable and generates ~26k log lines/day per cluster.

Your Environment

  • Calico version: v3.32.2 (tigera-operator v1.42.6, helm chart v3.32.2), aggregated API server mode
  • Calico dataplane: iptables
  • Orchestrator version: Kubernetes v1.35.8 (kubeadm, single node)
  • Operating System and version: Ubuntu 22.04.5 LTS, kernel 5.15.0-190-generic, containerd 2.3.3