kubernetes/kops · error
updating back-end for load-balancer %s: %w
Error message
updating back-end for load-balancer %s: %w
What it means
In LBBackend.RenderScw, when an existing backend differs from expected, kOps calls lb.ZonedAPI.UpdateBackend with the changed fields (port, protocol, algorithm, sticky sessions, proxy protocol). This error wraps a failure of that UpdateBackend call — the backend was found but could not be modified. Typically the request payload is rejected by Scaleway validation or the backend/LB is in a state that disallows updates.
Source
Thrown at upup/pkg/fi/cloudup/scalewaytasks/lb_backend.go:154
controlPlanesIPs, err := getControlPlanesIPs(t.Cloud, expected.LoadBalancer, zone)
if err != nil {
return err
}
if actual != nil {
_, err := lbService.UpdateBackend(&lb.ZonedAPIUpdateBackendRequest{
Zone: zone,
BackendID: fi.ValueOf(actual.ID),
Name: fi.ValueOf(actual.Name),
ForwardProtocol: lb.Protocol(fi.ValueOf(expected.ForwardProtocol)),
ForwardPort: fi.ValueOf(expected.ForwardPort),
ForwardPortAlgorithm: lb.ForwardPortAlgorithm(fi.ValueOf(expected.ForwardPortAlgorithm)),
StickySessions: lb.StickySessionsType(fi.ValueOf(expected.StickySessions)),
ProxyProtocol: lb.ProxyProtocol(fi.ValueOf(expected.ProxyProtocol)),
})
if err != nil {
return fmt.Errorf("updating back-end for load-balancer %s: %w", fi.ValueOf(actual.LoadBalancer.Name), err)
}
_, err = lbService.SetBackendServers(&lb.ZonedAPISetBackendServersRequest{
Zone: zone,
BackendID: fi.ValueOf(actual.ID),
ServerIP: controlPlanesIPs,
})
if err != nil {
return fmt.Errorf("updating back-end server IPs for load-balancer %s: %w", fi.ValueOf(actual.LoadBalancer.Name), err)
}
} else {
backendCreated, err := lbService.CreateBackend(&lb.ZonedAPICreateBackendRequest{
Zone: zone,
LBID: fi.ValueOf(expected.LoadBalancer.LBID),
Name: fi.ValueOf(expected.Name),
ForwardProtocol: lb.Protocol(fi.ValueOf(expected.ForwardProtocol)),View on GitHub (pinned to 4c8573c808)
Solutions
- Validate the cluster spec values against Scaleway enums: forward_port_algorithm (roundrobin|first|leastconn), sticky_sessions (none|cookie|table), proxy_protocol (proxy_protocol_v1|proxy_protocol_v2|proxy_protocol_unknown).
- Confirm the backend still exists (`scw lb backend list <lb-id>`) and re-run `kops update cluster` if it was deleted mid-apply.
- Wait for the LB to leave transient states (resetting/migrating) — `scw lb lb get` — then retry the apply.
- Check the SCW key has write permissions on the LB resource (IAM policy).
- If a validation error persists, run with --v=8 to inspect the exact UpdateBackend payload and fix the offending spec field.
Example fix
// before: spec value not a valid Scaleway enum
ForwardPortAlgorithm: fi.ValueOf("leastconn-tls")
// after: use an accepted Scaleway ForwardPortAlgorithm value
ForwardPortAlgorithm: fi.ValueOf("leastconn") Defensive patterns
Strategy: validation
Validate before calling
// validate enum-ish fields against Scaleway's accepted values before apply
var validAlgorithms = map[string]bool{"roundrobin": true, "first": true, "leastconn": true}
var validSticky = map[string]bool{"none": true, "cookie": true, "table": true}
var validProxy = map[string]bool{"proxy_protocol_none": true, "proxy_protocol_v1": true, "proxy_protocol_v2": true}
if !validAlgorithms[fi.ValueOf(b.ForwardPortAlgorithm)] ||
!validSticky[fi.ValueOf(b.StickySessions)] ||
!validProxy[fi.ValueOf(b.ProxyProtocol)] {
return fmt.Errorf("invalid backend enum in cluster spec")
} Type guard
func validBackendEnums(b *LBBackend) bool {
switch lb.ForwardPortAlgorithm(fi.ValueOf(b.ForwardPortAlgorithm)) {
case lb.ForwardPortAlgorithmRoundrobin, lb.ForwardPortAlgorithmFirst, lb.ForwardPortAlgorithmLeastconn:
default: return false
}
switch lb.ProxyProtocol(fi.ValueOf(b.ProxyProtocol)) {
case lb.ProxyProtocolProxyProtocolNone, lb.ProxyProtocolProxyProtocolV1, lb.ProxyProtocolProxyProtocolV2, lb.ProxyProtocolProxyProtocolUnknown:
default: return false
}
return true
} Try / catch
_, err := lbService.UpdateBackend(req)
if err != nil {
var respErr *scw.ResponseError
if errors.As(err, &respErr) && respErr.StatusCode == 409 {
return fmt.Errorf("LB in transient state, retry: %w", err) // retry after WaitForLb
}
return fmt.Errorf("updating back-end for load-balancer %s: %w", fi.ValueOf(actual.LoadBalancer.Name), err)
} Prevention
- Only use enum values accepted by scaleway-sdk-go lb types in the cluster spec
- Call WaitForLb before UpdateBackend so the LB is 'ready'
- Avoid concurrent applies to the same load balancer
- Grant the kOps API key LB write permissions in IAM
- Test spec changes with `kops update cluster --dry-run` first
When it happens
Trigger: lbService.UpdateBackend(&lb.ZonedAPIUpdateBackendRequest{...}) returns an error: invalid enum value cast from expected.ForwardPortAlgorithm/StickySessions/ProxyProtocol (invalid_argument), backend ID not found (deleted mid-apply), LB in 'resetting'/'migrating' transient state, or quota/validation rejection of the port/protocol combination.
Common situations: Cluster spec contains values outside Scaleway's accepted enums (e.g. proxy protocol string without the expected prefix, bad forward-port-algorithm like 'leastconn' vs 'roundrobin'/'first'/'leastconn' spelling); concurrent apply racing a Scaleway LB maintenance state; backend deleted manually during apply; permissions lacking lb edit rights.
Related errors
- unknown load balancer Type: %q
- cannot specify both %q and %q for forwarding rule target.
- scaleway cloud provider currently supports only one availabi
- deregistering cloud instance %s of group %q: %w
- deregistering cloud instance %s of group %q: listing load-ba
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/aa7eb18407c5e02c.
Report an issue: GitHub.