kubernetes/kops · error

error deleting security group rule: %v

Error message

error deleting security group rule: %v

What it means

This error is returned by deleteSecurityGroupRule when the Neutron security-group-rule Delete API fails with an error other than 404 Not Found, inside the writeBackoff retry loop. As with deleteSecurityGroup, a 404 is treated as success because the desired end state (rule gone) is already achieved. Any other error — auth failure, connectivity, or conflict — is wrapped and propagated after retries.

Source

Thrown at upup/pkg/fi/cloudup/openstack/security_group.go:167

	})
	if err != nil {
		return err
	} else if done {
		return nil
	} else {
		return wait.ErrWaitTimeout
	}
}

func (c *openstackCloud) DeleteSecurityGroupRule(ruleID string) error {
	return deleteSecurityGroupRule(c, ruleID)
}

func deleteSecurityGroupRule(c OpenstackCloud, ruleID string) error {
	done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
		err := sgr.Delete(context.TODO(), c.NetworkingClient(), ruleID).ExtractErr()
		if err != nil && !isNotFound(err) {
			return false, fmt.Errorf("error deleting security group rule: %v", err)
		}
		return true, nil
	})
	if err != nil {
		return err
	} else if done {
		return nil
	} else {
		return wait.ErrWaitTimeout
	}
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Confirm the rule ID exists in the right project (`openstack security group rule show <id>`); a genuinely missing rule is already handled as success
  2. Refresh OpenStack credentials if the wrapped error is 401
  3. Check RBAC policy on the networking service if 403
  4. Rerun the operation — writeBackoff retries transient 5xx/429 failures

Example fix

// before
err := sgr.Delete(context.TODO(), c.NetworkingClient(), ruleID).ExtractErr()
// after: pre-check existence to surface wrong-project/ID problems clearly
rule, err := sgr.Get(context.TODO(), c.NetworkingClient(), ruleID).Extract()
if err != nil { return fmt.Errorf("rule %q not accessible: %v", ruleID, err) }
_ = rule
err = sgr.Delete(context.TODO(), c.NetworkingClient(), ruleID).ExtractErr()
Defensive patterns

Strategy: try-catch

Validate before calling

_, err := sgr.Get(ctx, cloud.NetworkingClient(), ruleID).Extract()
if err != nil {
	if gophercloud.ResponseCodeIs(err, 404) { return nil } // already deleted
	return fmt.Errorf("rule %q not accessible before delete: %w", ruleID, err)
}

Type guard

func isRuleNotFound(err error) bool {
	var nf gophercloud.ErrDefault404
	return errors.As(err, &nf)
}

Try / catch

err := deleteSecurityGroupRule(c, ruleID)
if err != nil {
	if isRuleNotFound(err) { return nil } // treat as success
	var e401 gophercloud.ErrDefault401
	if errors.As(err, &e401) { /* reauthenticate and retry */ }
	return fmt.Errorf("deleting rule %s: %w", ruleID, err)
}

Prevention

When it happens

Trigger: sgr.Delete(context.TODO(), c.NetworkingClient(), ruleID).ExtractErr() returns an error where isNotFound(err) is false: expired/invalid token, RBAC denial, Neutron unreachable, or a 409 because the rule/group is concurrently being mutated.

Common situations: Teardown running after the token expired, rule already deleted by a concurrent reconcile (should surface as 404 and be ignored), or the rule ID no longer belonging to the caller's project (403/404 semantics differ across Neutron versions).

Related errors


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