{"record":{"id":"036f495ed7c596da","repo":"hashicorp/nomad","slug":"unable-to-read-usable-cores-w","errorCode":null,"errorMessage":"unable to read usable cores: %w","messagePattern":"unable to read usable cores: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/docker/driver.go","lineNumber":1015,"sourceCode":"\t\treturn minCPUShares\n\t}\n\treturn result\n}\n\n// cpuSet reads the available cores from the nomad client in order to assign\n// them to the new container, ensuring all tasks run in nomad assigned cpus.\nfunc (d *Driver) cpuSet(taskResources *drivers.Resources) (string, error) {\n\n\tif taskResources.LinuxResources != nil &&\n\t\ttaskResources.LinuxResources.CpusetCgroupPath == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\t// read the current value of usable cores\n\tsource := filepath.Join(taskResources.LinuxResources.CpusetCgroupPath, effectiveCpusetFile())\n\tb, err := os.ReadFile(source)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to read usable cores: %w\", err)\n\t}\n\n\treturn idset.Parse[hw.CoreID](string(b)).String(), nil\n}\n\nfunc (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *TaskConfig,\n\timageID string) (createContainerOptions, error) {\n\n\tlogger := d.logger.With(\"task_name\", task.Name)\n\tc := createContainerOptions{}\n\n\t// ensure that PortMap variables are populated early on\n\ttask.Env = taskenv.SetPortMapEnvs(task.Env, driverConfig.PortMap)\n\n\tif task.Resources == nil {\n\t\t// Guard against missing resources. We should never have been able to\n\t\t// schedule a job without specifying this.\n\t\tlogger.Error(\"task.Resources is empty\")","sourceCodeStart":997,"sourceCodeEnd":1033,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/docker/driver.go#L997-L1033","documentation":"cpuSet reads the effective CPU set of the task from cpuset cgroup file (cpuset.cpus.effective or cpuset.cpus) under the task's CpusetCgroupPath. If os.ReadFile of that file fails, Nomad cannot determine which cores the container may use and returns this wrapped error. It surfaces during createContainerConfig, i.e. at task start.","triggerScenarios":"The cpuset cgroup path for the task does not exist or is unreadable: cgroup v1/v2 mismatch (effectiveCpusetFile picks the wrong file), task cgroup already destroyed, cgroup filesystem not mounted, or permission denied reading /sys/fs/cgroup.","commonSituations":"Running Nomad in containers without /sys/fs/cgroup mounted; cgroup v1 systems where cpuset controller is not attached to the Nomad client's cgroup; hardened hosts restricting /sys reads; race where the task's cgroup was cleaned up before docker start.","solutions":["Verify /sys/fs/cgroup is mounted and contains cpuset.cpus(.effective) under the task's cgroup path; fix mounts (e.g. bind-mount cgroups into the Nomad container).","Check the cgroup v1 cpuset controller is enabled and attached to the client's cgroup hierarchy (cat /proc/cgroups, check cpuset subsystem).","Confirm file permissions — the nomad user must be able to read the cgroup files; check AppArmor/SELinux denials.","Upgrade Nomad / check effectiveCpusetFile behavior matches your cgroup version (cgroup.controllers present means v2)."],"exampleFix":"// docker run for nomad agent\n// before\ndocker run nomad\n// after\ndocker run -v /sys/fs/cgroup:/sys/fs/cgroup:ro nomad","handlingStrategy":"validation","validationCode":"function validateCgroupReadability() {\n  const base = '/sys/fs/cgroup';\n  const files = require('fs').existsSync(base + '/cgroup.controllers')\n    ? ['cgroup.cpuset.cpus.effective']\n    : ['cpuset/cpuset.cpus'];\n  for (const f of files) {\n    require('fs').accessSync(base + '/' + f);\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await driver.StartTask(taskCfg);\n} catch (err) {\n  if (/unable to read usable cores/.test(err.message)) {\n    // cgroup path missing/unreadable — check mounts and controller availability\n    log.error('cpuset cgroup unreadable; verify /sys/fs/cgroup mount and cpuset controller', { cause: err });\n  }\n  throw err;\n}","preventionTips":["Bind-mount /sys/fs/cgroup (ro) when running Nomad inside a container.","Confirm cgroup v1 cpuset controller is mounted on the client before joining the pool.","Monitor for cgroup v1→v2 migration on hosts; test driver cpu pinning after upgrade.","Check SELinux/AppArmor policies allow reading /sys/fs/cgroup for the nomad user."],"tags":["docker","cgroups","cpuset","linux"],"backgroundTag":"cgroup-read-failure","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}