ServiceL2Status reconcile loop floods the apiserver in v0.16.0 (regression from v0.15.3)
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 regression — v0.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
LoadBalancerService pulling a/32from anIPAddressPool+L2Advertisement - k3s v1.35.x, embedded etcd
- Namespace-independent — reproduced in both
metallb-systemand 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.
Source: metallb/metallb