kubernetes/kops · error
cannot apply changes to ForwardingRule: %v
Error message
cannot apply changes to ForwardingRule: %v
What it means
kOps GCE forwarding rules are effectively immutable: after applying label changes, any remaining diff between expected and actual state causes this error instead of attempting in-place modification. It tells you the cluster spec demands a field change (IP, target, network, ports, etc.) that the GCE API cannot apply to an existing rule.
Source
Thrown at upup/pkg/fi/cloudup/gcetasks/forwardingrule.go:277
if changes.Labels != nil {
req := compute.RegionSetLabelsRequest{
LabelFingerprint: a.labelFingerprint,
Labels: e.Labels,
}
op, err := t.Cloud.Compute().ForwardingRules().SetLabels(ctx, t.Cloud.Project(), t.Cloud.Region(), o.Name, &req)
if err != nil {
return fmt.Errorf("setting ForwardingRule labels: %w", err)
}
if err := t.Cloud.WaitForOp(op); err != nil {
return fmt.Errorf("setting ForwardRule labels: %w", err)
}
changes.Labels = nil
}
if !reflect.DeepEqual(changes, &ForwardingRule{}) {
return fmt.Errorf("cannot apply changes to ForwardingRule: %v", changes)
}
}
return nil
}
type terraformForwardingRule struct {
Name string `cty:"name"`
PortRange *string `cty:"port_range"`
Ports []string `cty:"ports"`
Target *terraformWriter.Literal `cty:"target"`
IPAddress *terraformWriter.Literal `cty:"ip_address"`
IPProtocol string `cty:"ip_protocol"`
LoadBalancingScheme *string `cty:"load_balancing_scheme"`
Network *terraformWriter.Literal `cty:"network"`
Subnetwork *terraformWriter.Literal `cty:"subnetwork"`
BackendService *terraformWriter.Literal `cty:"backend_service"`
Labels map[string]string `cty:"labels"`View on GitHub (pinned to 4c8573c808)
Solutions
- Identify the changed fields printed in the error and revert the spec change, or accept LB recreation: `kops update cluster` will not do it in place — delete and recreate the rule (often via `kops delete instancegroup`/changing loadBalancerType and re-creating)
- For API load balancers, changing the loadBalancerType typically requires recreating the load balancer resource; plan for downtime
- Diff current vs desired cluster spec (`kops get -oyaml`) to see which LB field changed
- Upgrade path note: some changes are handled by kOps internally by recreating tasks — ensure RuleIPAddress/observed state is refreshed before update
Example fix
// before: editing fields in place on an existing rule (unsupported)
// changes: {PortRange: "8080-8080"} -> error
// after: delete and re-apply the load balancer so the rule is recreated
kops delete cluster --name ... (or recreate the LB object), then
kops update cluster --yes Defensive patterns
Strategy: validation
Validate before calling
// before updating an existing rule, check only labels differ (labels are the only mutable field)
func onlyLabelsChanged(changes *ForwardingRule) bool {
c := *changes
c.Labels = nil
return reflect.DeepEqual(&c, &ForwardingRule{})
}
// if false, plan deletion+recreation of the rule instead of an update Try / catch
if !reflect.DeepEqual(changes, &ForwardingRule{}) {
return fmt.Errorf("cannot apply changes to ForwardingRule: %v (recreate the rule instead of updating)", changes)
} Prevention
- Treat GCE forwarding rules as immutable: expect recreation for IP/port/target/network changes
- Plan load-balancer downtime when changing loadBalancerType or target
- Diff `kops get cluster -oyaml` against running state before changing LB fields
- Check the printed changes struct to see exactly which field triggered recreation
When it happens
Trigger: RenderGCE with a != nil where, after clearing changes.Labels, reflect.DeepEqual(changes, &ForwardingRule{}) is false — i.e. changes to Name/IPAddress/PortRange/Target/Network/etc. remain.
Common situations: Changing loadBalancerType, port ranges, target pool, backend service, or static IP on an existing GCE load balancer; upgrading kOps and cluster spec fields shifting; editing the cluster spec LB settings directly.
Related errors
- Specified both IP Address and rule-managed IP address: %v, %
- error creating ForwardingRule %q: %v
- error creating forwarding rule: %v
- reading created ForwardingRule %q: %v
- setting ForwardingRule labels: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/51f2c731d890b6db.
Report an issue: GitHub.