Summary
When the CCM manages a Load Balancer (via scw-loadbalancer-id or by name lookup), it should treat the Kubernetes service definition as the authoritative source of truth and reconcile the LB to match — removing any frontends and backends that don't correspond to current service ports.
Current behaviour
The CCM attempts to delete stale backends that don't match the current service, but fails with a 400 Bad Request from the Scaleway API if a frontend still references the backend:
Error syncing load balancer: failed to ensure load balancer: failed deleting backend: <id> port: 30523
loadbalancer: <lb-id> err: scaleway-sdk-go: http error 400 Bad Request: Backend used by one or many frontend
The CCM doesn't attempt to remove the dependent frontend first, so it gets stuck in a retry loop and the service stays in ExternalIP: <pending> indefinitely.
This can happen whenever frontends/backends exist on the LB that the CCM didn't create in its current lifecycle — for example after a cluster rebuild reusing the same LB, or if the LB was modified outside the CCM.
Expected behaviour
The CCM should fully reconcile the LB state on each sync:
- Determine the desired set of frontends and backends from the Kubernetes service spec
- Remove any frontends that don't match the desired state (this unblocks backend deletion)
- Remove any backends that don't match the desired state
- Create/update frontends and backends to match the desired state
This aligns with Scaleway's own documentation which states: "Any modifications made to the configuration of your Kubernetes cluster's Load Balancer via the Scaleway console, the API, or any other developer tools, will be overwritten by the cluster's CCM."
Currently this isn't the case — stale configuration is not overwritten, it blocks reconciliation.
Environment
- Scaleway Kapsule (managed Kubernetes)
- LB reused via
service.beta.kubernetes.io/scw-loadbalancer-id annotation
Summary
When the CCM manages a Load Balancer (via
scw-loadbalancer-idor by name lookup), it should treat the Kubernetes service definition as the authoritative source of truth and reconcile the LB to match — removing any frontends and backends that don't correspond to current service ports.Current behaviour
The CCM attempts to delete stale backends that don't match the current service, but fails with a
400 Bad Requestfrom the Scaleway API if a frontend still references the backend:The CCM doesn't attempt to remove the dependent frontend first, so it gets stuck in a retry loop and the service stays in
ExternalIP: <pending>indefinitely.This can happen whenever frontends/backends exist on the LB that the CCM didn't create in its current lifecycle — for example after a cluster rebuild reusing the same LB, or if the LB was modified outside the CCM.
Expected behaviour
The CCM should fully reconcile the LB state on each sync:
This aligns with Scaleway's own documentation which states: "Any modifications made to the configuration of your Kubernetes cluster's Load Balancer via the Scaleway console, the API, or any other developer tools, will be overwritten by the cluster's CCM."
Currently this isn't the case — stale configuration is not overwritten, it blocks reconciliation.
Environment
service.beta.kubernetes.io/scw-loadbalancer-idannotation