cilium/cilium · error
failed while adding peer %s with ASN %d: %w
Error message
failed while adding peer %s with ASN %d: %w
What it means
AddNeighbor wraps errors from the gobgp server's AddPeer gRPC call when installing a new BGP peering in the GoBGP control plane. It preserves the peer address and ASN in the message for debugging.
Source
Thrown at pkg/bgp/gobgp/peer.go:23
import (
"context"
"fmt"
"net/netip"
gobgp "github.com/osrg/gobgp/v4/api"
"github.com/cilium/cilium/pkg/bgp/types"
)
// AddNeighbor will add the CiliumBGPNeighbor to the gobgp.BgpServer, creating
// a BGP peering connection.
func (g *GoBGPServer) AddNeighbor(ctx context.Context, n *types.Neighbor) error {
peerReq := &gobgp.AddPeerRequest{
Peer: ToGoBGPPeer(n, nil, n.Address.Is4()),
}
if err := g.server.AddPeer(ctx, peerReq); err != nil {
return fmt.Errorf("failed while adding peer %s with ASN %d: %w", n.Address, n.ASN, err)
}
return nil
}
// UpdateNeighbor will update the existing CiliumBGPNeighbor in the gobgp.BgpServer.
func (g *GoBGPServer) UpdateNeighbor(ctx context.Context, n *types.Neighbor) error {
oldPeer, err := g.getExistingPeer(ctx, n.Address, n.ASN)
if err != nil {
return fmt.Errorf("failed to get existing peer: %w", err)
}
newPeer := ToGoBGPPeer(n, oldPeer, n.Address.Is4())
needsHardReset := g.needsHardReset(oldPeer, newPeer)
// update peer config
peerReq := &gobgp.UpdatePeerRequest{
Peer: ToGoBGPPeer(n, oldPeer, n.Address.Is4()),View on GitHub (pinned to ac7b90affa)
Solutions
- Read the wrapped %w error for the root gobgp failure and fix the neighbor config accordingly
- Check for an existing peer with the same address but different ASN; remove or update it instead of adding
- Verify the neighbor's Address parses to a valid IP and ASN is the intended value
- Use UpdateNeighbor (reconcile) rather than AddNeighbor when the peer may already exist
- If it's a transient gRPC/startup race, retry after the server is ready
Example fix
// before
err := server.AddNeighbor(ctx, n) // fails if peer exists
// after
if _, getErr := server.getExistingPeer(ctx, n.Address, n.ASN); getErr == nil {
err = server.UpdateNeighbor(ctx, n)
} else {
err = server.AddNeighbor(ctx, n)
} Defensive patterns
Strategy: try-catch
Validate before calling
if n.Address == nil || n.ASN == 0 {
return errors.New("neighbor needs a valid Address and non-zero ASN")
}
if _, err := server.GetNeighbor(ctx, n.Address, n.ASN); err == nil {
return errors.New("peer already exists; use UpdateNeighbor")
} Try / catch
err := server.AddNeighbor(ctx, n)
var existing *types.ExistingNeighborRelationError
if err != nil && strings.Contains(err.Error(), "exceeds max limit") {
err = server.UpdateNeighbor(ctx, n)
} Prevention
- Make reconciliation idempotent: check-then-add or upsert semantics
- Validate IP address and ASN before calling AddNeighbor
- Retry transient gRPC errors with backoff
- Log the wrapped gobgp error for root cause
When it happens
Trigger: Calling GoBGPServer.AddNeighbor when the underlying g.server.AddPeer rejects the peer — invalid peer address/ASN combination, duplicate/conflicting peering already configured, gobgp not yet started, or gRPC transport errors to the embedded server.
Common situations: Applying a CiliumBGPNeighbor whose peer already exists with a different ASN; malformed neighbor address in the CiliumBGPNodeConfig; BGP control-plane not fully initialized at reconcile time; transient gRPC unavailability.
Related errors
- failed to get existing peer: %w
- failed while updating peer %v:%v with ASN %v: %w
- failed while resetting peer %v:%v in ASN %v: %w
- listing peers failed: %w
- no active default route found
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/3228dbde5c3bdb6b.
Report an issue: GitHub.