kubernetes/kops · error
SourceRanges and SourceTags should not both be specified
Error message
SourceRanges and SourceTags should not both be specified
What it means
GCE treats SourceRanges and SourceTags as OR, not AND, which developers usually do not expect. Normalize rejects specs that set both so kOps never creates a rule that is broader than the author intended.
Source
Thrown at upup/pkg/fi/cloudup/gcetasks/firewallrule.go:110
func (e *FirewallRule) Run(c *fi.CloudupContext) error {
return fi.CloudupDefaultDeltaRunMethod(e, c)
}
// Normalize applies some validation that isn't technically required,
// but avoids some problems with surprising behaviours.
func (e *FirewallRule) Normalize(c *fi.CloudupContext) error {
if !e.Disabled {
// Treat it as an error if SourceRanges _and_ SourceTags empty with Disabled=false
// this is interpreted as SourceRanges="0.0.0.0/0", which is likely not what was intended.
if len(e.SourceRanges) == 0 && len(e.SourceTags) == 0 {
return fmt.Errorf("either SourceRanges or SourceTags should be specified when Disabled is false")
}
}
// Treat it as an error if SourceRanges _and_ SourceTags both set;
// this is interpreted as OR, not AND, which is likely not what was intended.
if len(e.SourceRanges) != 0 && len(e.SourceTags) != 0 {
return fmt.Errorf("SourceRanges and SourceTags should not both be specified")
}
name := fi.ValueOf(e.Name)
// Make sure we've split the ipv4 / ipv6 addresses.
// A single firewall rule can't mix ipv4 and ipv6 addresses, so we split them into two rules.
for _, sourceRange := range e.SourceRanges {
_, cidr, err := net.ParseCIDR(sourceRange)
if err != nil {
return fmt.Errorf("sourceRange %q is not valid: %w", sourceRange, err)
}
if e.Family == "" {
// This is our own requirement, just for consistency checking.
// Previous we used the name, but that was confused when the cluster name was ipv6.example.com
return fmt.Errorf("must set Family when using SourceRanges")
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Keep only sourceRanges if CIDR restriction is intended
- Keep only sourceTags if tag-based restriction is intended
- Split into two separate FirewallRule tasks if you genuinely need both rule types
- Re-run kops update after editing the manifest
Example fix
// before sourceRanges: ["10.0.0.0/8"] sourceTags: ["my-tag"] // after sourceRanges: ["10.0.0.0/8"]
Defensive patterns
Strategy: validation
Validate before calling
func validateExclusiveSources(rule FirewallRuleSpec) error {
if len(rule.SourceRanges) != 0 && len(rule.SourceTags) != 0 {
return fmt.Errorf("rule %s: use sourceRanges OR sourceTags, not both (GCE ORs them)", rule.Name)
}
return nil
} Prevention
- Remember GCE semantics: ranges and tags are ORed
- Split into two rules when both dimensions are needed
- Code-review firewall manifest changes for combined sources
When it happens
Trigger: A firewallRule in the cluster spec has non-empty sourceRanges AND non-empty sourceTags simultaneously.
Common situations: Merging two rule configs during refactoring; assuming the fields combine as AND; copy-pasting rules that each had only one of the fields.
Related errors
- either SourceRanges or SourceTags should be specified when D
- sourceRange %q is not valid: %w
- must set Family when using SourceRanges
- ipv4 ranges should not be in a ipv6-named rule (found %s in
- error deleting FirewallRule %s: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d830fc66dc410a87.
Report an issue: GitHub.