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

  1. Read the wrapped %w error for the root gobgp failure and fix the neighbor config accordingly
  2. Check for an existing peer with the same address but different ASN; remove or update it instead of adding
  3. Verify the neighbor's Address parses to a valid IP and ASN is the intended value
  4. Use UpdateNeighbor (reconcile) rather than AddNeighbor when the peer may already exist
  5. 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

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


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