{"record":{"id":"dccc32c53a0a6ecd","repo":"cilium/cilium","slug":"get-local-node-w","errorCode":null,"errorMessage":"get local node: %w","messagePattern":"get local node: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/envoy/locality.go","lineNumber":30,"sourceCode":"\tenvoy_config_core \"github.com/envoyproxy/go-control-plane/envoy/config/core/v3\"\n\t\"google.golang.org/protobuf/types/known/durationpb\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\n\tconfig \"github.com/cilium/cilium/pkg/envoy/config\"\n\t\"github.com/cilium/cilium/pkg/node\"\n)\n\n// Keep the constant public to make it accessible in downstream repos.\nconst LocalityClusterName = \"/cilium-locality-cluster\"\n\nfunc getLocalNodeZone(localNodeStore *node.LocalNodeStore) (string, error) {\n\tif localNodeStore == nil {\n\t\treturn \"\", fmt.Errorf(\"local node store is unavailable\")\n\t}\n\n\tlocalNode, err := localNodeStore.Get(context.Background())\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"get local node: %w\", err)\n\t}\n\n\treturn localNode.Labels[corev1.LabelTopologyZone], nil\n}\n\nfunc appendEmbeddedLocalityBootstrap(bs *envoy_config_bootstrap.Bootstrap, xdsMode config.XDSMode, connectTimeout int64, zone string) {\n\tif bs.GetNode() == nil {\n\t\tbs.Node = &envoy_config_core.Node{}\n\t}\n\tif bs.StaticResources == nil {\n\t\tbs.StaticResources = &envoy_config_bootstrap.Bootstrap_StaticResources{}\n\t}\n\tif bs.ClusterManager == nil {\n\t\tbs.ClusterManager = &envoy_config_bootstrap.ClusterManager{}\n\t}\n\tbs.ClusterManager.LocalClusterName = LocalityClusterName\n\tbs.StaticResources.Clusters = append(bs.StaticResources.Clusters, newLocalityCluster(xdsMode, connectTimeout))\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/envoy/locality.go#L12-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"Very early startup where Envoy bootstrap is generated before node discovery completes; shutdown racing bootstrap generation; embedded usages that never publish a local node.","solutions":["Check the wrapped cause (%w) — usually context.DeadlineExceeded or Canceled","Ensure the local node watcher starts and publishes the node before Envoy bootstrap generation","Avoid generating the bootstrap with an already-expired/cancelled context","Add startup ordering so node discovery precedes Envoy provisioning"],"exampleFix":"// before\nzone, err := getLocalNodeZone(store) // ctx already cancelled\n// after\nctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\ndefer cancel()\nzone, err := getLocalNodeZoneWithCtx(ctx, store)","handlingStrategy":"retry","validationCode":"// ensure a node object is observable before generating bootstrap\nnode, err := localNodeStore.Get(ctx)\nif err != nil {\n    return fmt.Errorf(\"local node not yet discovered: %w\", err)\n}\n_ = node","typeGuard":null,"tryCatchPattern":"zone, err := getLocalNodeZone(store)\nif errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {\n    // retry with backoff after node discovery completes\n}","preventionTips":["Order startup: node discovery before Envoy bootstrap generation","Use a sufficiently long-lived context for bootstrap generation","Avoid invoking bootstrap generation during shutdown"],"tags":["envoy","locality","node-store","context"],"backgroundTag":"node-discovery-not-ready","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}