kubernetes/kops · error

Specified both IP Address and rule-managed IP address: %v, %

Error message

Specified both IP Address and rule-managed IP address: %v, %v

What it means

kOps's GCE ForwardingRule task refuses to reconcile a forwarding rule when the model contains two competing sources for the rule's IP: an explicit IPAddress task reference and a RuleIPAddress (an IP managed by the rule itself, e.g. allocated by the load balancer). This is a config-validation guard thrown before any GCE API call, because only one IP source can be applied.

Source

Thrown at upup/pkg/fi/cloudup/gcetasks/forwardingrule.go:203

	if e.IPAddress != nil {
		o.IPAddress = fi.ValueOf(e.IPAddress.IPAddress)
		if o.IPAddress == "" {
			addr, err := e.IPAddress.find(t.Cloud)
			if err != nil {
				return fmt.Errorf("error finding Address %q: %v", e.IPAddress, err)
			}
			if addr == nil {
				return fmt.Errorf("Address %q was not found", e.IPAddress)
			}

			o.IPAddress = fi.ValueOf(addr.IPAddress)
			if o.IPAddress == "" {
				return fmt.Errorf("Address had no IP: %v", e.IPAddress)
			}
		}
	}
	if o.IPAddress != "" && e.RuleIPAddress != nil {
		return fmt.Errorf("Specified both IP Address and rule-managed IP address: %v, %v", e.IPAddress, *e.RuleIPAddress)
	}
	if e.RuleIPAddress != nil {
		o.IPAddress = *e.RuleIPAddress
	}

	if e.Network != nil {
		project := t.Cloud.Project()
		if e.Network.Project != nil {
			project = *e.Network.Project
		}
		o.Network = e.Network.URL(project)
	}

	if e.Subnetwork != nil {
		project := t.Cloud.Project()
		if e.Network.Project != nil {
			project = *e.Network.Project
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Pick one IP source: either set an explicit IPAddress task (static IP) or rely on the rule-managed IP, not both
  2. If pinning a static IP, ensure RuleIPAddress is nil in the task spec (recreate the task or let kOps re-discover state)
  3. Re-run kops update after fixing the cluster spec so the observed RuleIPAddress is cleared

Example fix

// before: both set on the ForwardingRule task
rule.IPAddress = staticAddrTask
rule.RuleIPAddress = fi.PtrTo(existingIP)

// after: explicit static IP only
rule.IPAddress = staticAddrTask
rule.RuleIPAddress = nil
Defensive patterns

Strategy: validation

Validate before calling

// before creating/updating a GCE ForwardingRule task
func validateForwardingRuleIP(rule *ForwardingRule) error {
    hasExplicit := rule.IPAddress != nil && rule.IPAddress.IPAddress != nil && *rule.IPAddress.IPAddress != ""
    if hasExplicit && rule.RuleIPAddress != nil {
        return fmt.Errorf("set either IPAddress (%v) or RuleIPAddress (%v), not both", *rule.IPAddress.IPAddress, *rule.RuleIPAddress)
    }
    return nil
}

Type guard

func hasExplicitIP(rule *ForwardingRule) bool {
    return rule.IPAddress != nil && rule.IPAddress.IPAddress != nil && *rule.IPAddress.IPAddress != ""
}
func hasRuleManagedIP(rule *ForwardingRule) bool { return rule.RuleIPAddress != nil }

Prevention

When it happens

Trigger: RenderGCE is called with a ForwardingRule whose IPAddress task resolves to a non-empty IP (o.IPAddress != "") while e.RuleIPAddress is also non-nil. Both fields are populated in the same task spec.

Common situations: Cluster spec migration: a rule that previously let GCE pick its IP (RuleIPAddress set from the discovered/observed state) is edited to pin an explicit static Address without clearing the stored RuleIPAddress; upgrading clusters between load-balancer modes; hand-edited manifests specifying both.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/4a14e47d5cc29ce5. Report an issue: GitHub.