kubernetes/kubernetes · error

unable to discover CPU topology info: %s

Error message

unable to discover CPU topology info: %s

What it means

From getReservedCPUs (server.go:641-643): topology.Discover failed while building the CPU topology needed to validate --reserved-cpus. Discover reads /sys/devices/system/cpu/* (and NUMA info) to learn which CPUs exist and their attributes, so failure means the kernel's sysfs CPU topology could not be parsed.

Source

Thrown at cmd/kubelet/app/server.go:643

	eventBroadcaster.StartStructuredLogging(3)
	if kubeDeps.EventClient != nil {
		logger.V(4).Info("Sending events to api server")
		eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeDeps.EventClient.Events("")})
	} else {
		logger.Info("No api server defined - no events will be sent to API server")
	}
}

func getReservedCPUs(logger klog.Logger, machineInfo *cadvisorapi.MachineInfo, cpus string) (cpuset.CPUSet, error) {
	emptyCPUSet := cpuset.New()

	if cpus == "" {
		return emptyCPUSet, nil
	}

	topo, err := topology.Discover(logger, machineInfo)
	if err != nil {
		return emptyCPUSet, fmt.Errorf("unable to discover CPU topology info: %s", err)
	}
	reservedCPUSet, err := cpuset.Parse(cpus)
	if err != nil {
		return emptyCPUSet, fmt.Errorf("unable to parse reserved-cpus list: %s", err)
	}
	allCPUSet := topo.CPUDetails.CPUs()
	if !reservedCPUSet.IsSubsetOf(allCPUSet) {
		return emptyCPUSet, fmt.Errorf("reserved-cpus: %s is not a subset of online-cpus: %s", cpus, allCPUSet.String())
	}
	return reservedCPUSet, nil
}

func run(ctx context.Context, s *options.KubeletServer, kubeDeps *kubelet.Dependencies, featureGate featuregate.FeatureGate) (err error) {
	logger := klog.FromContext(ctx)
	// NewHealthChecker returns an error indicating that the watchdog is configured but the configuration is incorrect,
	// the kubelet will not be started.
	healthChecker, err := watchdog.NewHealthChecker(logger)
	if err != nil {

View on GitHub (pinned to b882c60b40)

Solutions

  1. Ensure /sys is mounted and readable in the kubelet's environment (`ls /sys/devices/system/cpu/`).
  2. Update the kernel / hypervisor if sysfs CPU entries are inconsistent.
  3. If you do not actually need reserved CPUs, clear --reserved-cpus to bypass this code path.
  4. Retry on a stable host after any hotplug has settled.
Defensive patterns

Strategy: validation

Validate before calling

// Preflight: only set --reserved-cpus if topology can be discovered.
if _, err := topology.Discover(logger, machineInfo); err != nil {
    return fmt.Errorf("cannot use --reserved-cpus: topology discovery failed: %w", err)
}

Prevention

When it happens

Trigger: Triggered only when --reserved-cpus is non-empty AND topology.Discover errors — i.e. the kubelet is configured for static CPU management with reserved CPUs but cannot enumerate online CPUs from sysfs. Common on misconfigured containers or unusual kernels where /sys is not mounted or CPU entries are inconsistent.

Common situations: Running kubelet in a container without /sys mounted read-only; a kernel/driver bug producing inconsistent /sys/devices/system/cpu entries; hotplug races during discovery; highly virtualized environments exposing a weird topology.

Related errors


AI-assisted analysis of kubernetes/kubernetes@b882c60b40 (2026-08-07). Data as JSON: /api/errors/92b67921650e3d1b. Report an issue: GitHub.