cilium/cilium · error

unable to get nodes' cluster: %w

Error message

unable to get nodes' cluster: %w

What it means

The cilium-health server's getNodes (pkg/health/server/server.go:96) asks the main Cilium daemon for the cluster node list via s.Daemon.GetClusterNodes (the /cluster/nodes API), which the health daemon uses to probe peer nodes. This error wraps any failure of that client call with %w.

Source

Thrown at pkg/health/server/server.go:96

}

// getNodes fetches the nodes added and removed from the last time the server
// made a request to the daemon.
func (s *Server) getNodes() (nodeMap, nodeMap, error) {
	scopedLog := s.logger
	if s.CiliumURI != "" {
		scopedLog = s.logger.With(logfields.URI, s.CiliumURI)
	}
	scopedLog.Debug("Sending request for /cluster/nodes ...")

	clusterNodesParam := daemon.NewGetClusterNodesParams()
	s.RWMutex.RLock()
	cID := s.clientID
	s.RWMutex.RUnlock()
	clusterNodesParam.SetClientID(&cID)
	resp, err := s.Daemon.GetClusterNodes(clusterNodesParam)
	if err != nil {
		return nil, nil, fmt.Errorf("unable to get nodes' cluster: %w", err)
	}
	scopedLog.Debug("Got cilium /cluster/nodes")

	if resp == nil || resp.Payload == nil {
		return nil, nil, fmt.Errorf("received nil health response")
	}

	s.RWMutex.Lock()
	s.clientID = resp.Payload.ClientID

	if resp.Payload.Self != "" {
		s.localStatus = &healthModels.SelfStatus{
			Name: resp.Payload.Self,
		}
	}
	s.RWMutex.Unlock()

	nodesAdded := nodeElementSliceToNodeMap(resp.Payload.NodesAdded, option.Config.PreferIpv6)

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Check the wrapped cause to distinguish socket-unreachable vs API error
  2. Verify the Cilium agent is up and its API socket exists (cilium status)
  3. Retry — getNodes is called from runActiveServices which repeats periodically; a transient agent restart self-heals
  4. Confirm agent/health-daemon API versions match (no skewed upgrade)
  5. Inspect agent logs for errors serving /cluster/nodes (e.g. KVStore/cluster connectivity problems)
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.Stat(agentSocketPath); err != nil {
	return fmt.Errorf("agent API socket unavailable: %w", err) // skip probe round
}

Try / catch

nodes, _, err := getNodes(ctx)
if err != nil {
	log.WithError(err).Debug("getNodes failed; will retry next interval")
	return // runActiveServices retries periodically
}

Prevention

When it happens

Trigger: Daemon.GetClusterNodes(clusterNodesParam) returns an error: the agent API is unreachable (socket missing/refused), the request fails/times out, or the API returns an error payload.

Common situations: Agent restarting while health daemon probes continue; agent API socket permissions or path issues; API version skew between health server and daemon; agent overloaded causing request timeouts.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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