cilium/cilium · error

get local node: %w

Error message

get local node: %w

What it means

After confirming LocalNodeStore is non-nil, getLocalNodeZone calls localNodeStore.Get(ctx) to fetch the current local node object; if that fetch fails (e.g. the context is cancelled or the store has not yet observed a node), the error is wrapped as 'get local node: %w'. The bootstrap cannot embed the locality zone without it.

Source

Thrown at pkg/envoy/locality.go:30

	envoy_config_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
	"google.golang.org/protobuf/types/known/durationpb"
	corev1 "k8s.io/api/core/v1"

	config "github.com/cilium/cilium/pkg/envoy/config"
	"github.com/cilium/cilium/pkg/node"
)

// Keep the constant public to make it accessible in downstream repos.
const LocalityClusterName = "/cilium-locality-cluster"

func getLocalNodeZone(localNodeStore *node.LocalNodeStore) (string, error) {
	if localNodeStore == nil {
		return "", fmt.Errorf("local node store is unavailable")
	}

	localNode, err := localNodeStore.Get(context.Background())
	if err != nil {
		return "", fmt.Errorf("get local node: %w", err)
	}

	return localNode.Labels[corev1.LabelTopologyZone], nil
}

func appendEmbeddedLocalityBootstrap(bs *envoy_config_bootstrap.Bootstrap, xdsMode config.XDSMode, connectTimeout int64, zone string) {
	if bs.GetNode() == nil {
		bs.Node = &envoy_config_core.Node{}
	}
	if bs.StaticResources == nil {
		bs.StaticResources = &envoy_config_bootstrap.Bootstrap_StaticResources{}
	}
	if bs.ClusterManager == nil {
		bs.ClusterManager = &envoy_config_bootstrap.ClusterManager{}
	}
	bs.ClusterManager.LocalClusterName = LocalityClusterName
	bs.StaticResources.Clusters = append(bs.StaticResources.Clusters, newLocalityCluster(xdsMode, connectTimeout))

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Check the wrapped cause (%w) — usually context.DeadlineExceeded or Canceled
  2. Ensure the local node watcher starts and publishes the node before Envoy bootstrap generation
  3. Avoid generating the bootstrap with an already-expired/cancelled context
  4. Add startup ordering so node discovery precedes Envoy provisioning

Example fix

// before
zone, err := getLocalNodeZone(store) // ctx already cancelled
// after
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
zone, err := getLocalNodeZoneWithCtx(ctx, store)
Defensive patterns

Strategy: retry

Validate before calling

// ensure a node object is observable before generating bootstrap
node, err := localNodeStore.Get(ctx)
if err != nil {
    return fmt.Errorf("local node not yet discovered: %w", err)
}
_ = node

Try / catch

zone, err := getLocalNodeZone(store)
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
    // retry with backoff after node discovery completes
}

Prevention

When it happens

Trigger: The context passed in is already cancelled or times out while waiting for the local node object; the node store was created but never populated with a LocalNode observation before bootstrap generation runs.

Common situations: Very early startup where Envoy bootstrap is generated before node discovery completes; shutdown racing bootstrap generation; embedded usages that never publish a local node.

Related errors


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