cilium/cilium · error

failed adding policy %s: %w

Error message

failed adding policy %s: %w

What it means

After defined sets are added, AddRoutePolicy registers the policy itself via the server's AddPolicy. On failure it rolls back the created defined sets and wraps the error with the policy name. The policy was rejected by GoBGP - typically because a policy with the same name exists or the policy references statements/sets gobgp considers invalid.

Source

Thrown at pkg/bgp/gobgp/server.go:291

// AddRoutePolicy adds a new routing policy into the global policies of the server.
func (g *GoBGPServer) AddRoutePolicy(ctx context.Context, r types.RoutePolicyRequest) error {
	if r.Policy == nil {
		return fmt.Errorf("nil policy in the RoutePolicyRequest")
	}
	policy, definedSets := toGoBGPPolicy(r.Policy)

	for i, ds := range definedSets {
		err := g.server.AddDefinedSet(ctx, &gobgp.AddDefinedSetRequest{DefinedSet: ds})
		if err != nil {
			g.deleteDefinedSets(ctx, definedSets[:i]) // clean up already created defined sets
			return fmt.Errorf("failed adding policy defined set %s: %w", ds.Name, err)
		}
	}

	err := g.server.AddPolicy(ctx, &gobgp.AddPolicyRequest{Policy: policy})
	if err != nil {
		g.deleteDefinedSets(ctx, definedSets) // clean up defined sets
		return fmt.Errorf("failed adding policy %s: %w", policy.Name, err)
	}

	// Note that we are using global policy assignment here (per-neighbor policies work only in the route-server mode)
	assignment := g.getGlobalPolicyAssignment(policy, r.Policy.Type, r.DefaultExportAction)
	err = g.server.AddPolicyAssignment(ctx, &gobgp.AddPolicyAssignmentRequest{Assignment: assignment})
	if err != nil {
		g.deletePolicy(ctx, policy)           // clean up policy
		g.deleteDefinedSets(ctx, definedSets) // clean up defined sets
		return fmt.Errorf("failed adding policy assignment %s: %w", assignment.Name, err)
	}

	return nil
}

// RemoveRoutePolicy removes a routing policy from the global policies of the server.
func (g *GoBGPServer) RemoveRoutePolicy(ctx context.Context, r types.RoutePolicyRequest) error {
	if r.Policy == nil {
		return fmt.Errorf("nil policy in the RoutePolicyRequest")

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Read the wrapped error for the exact gobgp rejection (AlreadyExists vs validation)
  2. Make reconciliation idempotent: remove or diff the existing policy before AddRoutePolicy
  3. Check the policy name for collisions across multiple CiliumBGPPolicy objects
  4. Validate statement structure (match conditions, actions, default export action) before applying

Example fix

// before
err := bgpServer.AddRoutePolicy(ctx, req) // fails: policy already exists
// after
if err := bgpServer.RemoveRoutePolicy(ctx, req); err != nil && !errors.Is(err, ErrPolicyNotFound) {
    return err
}
err := bgpServer.AddRoutePolicy(ctx, req)
Defensive patterns

Strategy: validation

Validate before calling

if req.Policy == nil || req.Policy.Name == "" { return fmt.Errorf("policy needs a name") }
for _, s := range req.Policy.Statements {
    if len(s.MatchPrefixes) == 0 && len(s.MatchNeighbors) == 0 { return fmt.Errorf("statement has no match clauses") }
}
err := srv.AddRoutePolicy(ctx, req)

Type guard

func namedPolicy(r types.RoutePolicyRequest) bool { return r.Policy != nil && r.Policy.Name != "" }

Try / catch

err := srv.AddRoutePolicy(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed adding policy") {
    // policy name likely already exists: replace idempotently
    _ = srv.RemoveRoutePolicy(ctx, req)
    err = srv.AddRoutePolicy(ctx, req)
}

Prevention

When it happens

Trigger: AddRoutePolicy with a policy whose name collides with an existing one, or whose statements (match clauses/actions) fail gobgp validation after the defined sets were accepted.

Common situations: Re-applying an unchanged policy on every reconcile (name already exists); malformed match/route-action combos in the CRD; leftover policy state from a previous crashed reconciliation.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/999eb009b6ed46ff. Report an issue: GitHub.