#3063·metallb

ServiceL2Status reconcile loop floods the apiserver in v0.16.0 (regression from v0.15.3)

Author: mzacCreated May 22, 2026Updated Jul 29, 2026
Labelsbug

Summary

In L2 mode, the speaker's servicel2status controller enters a tight failing-reconcile loop in v0.16.0, generating ~5–6 errors/sec per LoadBalancer service against the apiserver. It is a regressionv0.15.3 (and earlier) does not exhibit it.

Symptoms

Speaker logs, alternating at ~5/sec:

Reconciler error  controller=servicel2status  namespace=<ns>  name=<svc>
  error="resourceVersion should not be set on objects to be created"
Reconciler error  controller=servicel2status  namespace=<ns>  name=<svc>
  error="servicel2statuses.metallb.io \"l2-<rand>\" not found"

The apiserver logs the matching error at the same rate:

"Unhandled Error" err="apiserver received an error that is not an metav1.Status:
&errors.errorString{s:\"resourceVersion should not be set on objects to be created\"}:
resourceVersion should not be set on objects to be created"

The per-service ServiceL2Status object churns (create-fails-with-resourceVersion → not-found → recreate via generateName). On a small k3s / embedded-etcd cluster this pins the apiserver + etcd (visible CPU + "apply request took too long" etcd warnings). The VIP is announced correctly the entire time — the impact is CPU/etcd load + log flooding, not a connectivity outage (which distinguishes it from #2705).

Clean version bisection

Same 3-node k3s cluster, same CRDs, only the controller + speaker image tag changed (crds.enabled=false, reusing the v0.16.0 CRDs, which are schema-compatible):

Version servicel2status reconcile errs / 30s apiserver resourceVersion errs / 30s
v0.16.0 ~203 ~41
v0.15.3 ~0 0

Environment / repro

  • MetalLB L2 mode, 3 speakers (DaemonSet across 3 nodes)
  • One LoadBalancer Service pulling a /32 from an IPAddressPool + L2Advertisement
  • k3s v1.35.x, embedded etcd
  • Namespace-independent — reproduced in both metallb-system and a non-default namespace
  • Downgrading the controller+speaker images to v0.15.3 (keeping everything else identical) eliminates the churn

Related

#2705 — same servicel2statuses ... "l2-<rand>" not found reconcile churn, reported on 0.14.8 (there it manifested as advertisement-on-wrong-node / connectivity loss). This issue adds the clean v0.15.3→v0.16.0 regression boundary.