hashicorp/nomad · error
unable to read usable cores: %w
Error message
unable to read usable cores: %w
What it means
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.
Source
Thrown at drivers/docker/driver.go:1015
return minCPUShares
}
return result
}
// cpuSet reads the available cores from the nomad client in order to assign
// them to the new container, ensuring all tasks run in nomad assigned cpus.
func (d *Driver) cpuSet(taskResources *drivers.Resources) (string, error) {
if taskResources.LinuxResources != nil &&
taskResources.LinuxResources.CpusetCgroupPath == "" {
return "", nil
}
// read the current value of usable cores
source := filepath.Join(taskResources.LinuxResources.CpusetCgroupPath, effectiveCpusetFile())
b, err := os.ReadFile(source)
if err != nil {
return "", fmt.Errorf("unable to read usable cores: %w", err)
}
return idset.Parse[hw.CoreID](string(b)).String(), nil
}
func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *TaskConfig,
imageID string) (createContainerOptions, error) {
logger := d.logger.With("task_name", task.Name)
c := createContainerOptions{}
// ensure that PortMap variables are populated early on
task.Env = taskenv.SetPortMapEnvs(task.Env, driverConfig.PortMap)
if task.Resources == nil {
// Guard against missing resources. We should never have been able to
// schedule a job without specifying this.
logger.Error("task.Resources is empty")View on GitHub (pinned to 482b49bf1a)
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).
Example fix
// docker run for nomad agent // before docker run nomad // after docker run -v /sys/fs/cgroup:/sys/fs/cgroup:ro nomad
Defensive patterns
Strategy: validation
Validate before calling
function validateCgroupReadability() {
const base = '/sys/fs/cgroup';
const files = require('fs').existsSync(base + '/cgroup.controllers')
? ['cgroup.cpuset.cpus.effective']
: ['cpuset/cpuset.cpus'];
for (const f of files) {
require('fs').accessSync(base + '/' + f);
}
return true;
} Try / catch
try {
await driver.StartTask(taskCfg);
} catch (err) {
if (/unable to read usable cores/.test(err.message)) {
// cgroup path missing/unreadable — check mounts and controller availability
log.error('cpuset cgroup unreadable; verify /sys/fs/cgroup mount and cpuset controller', { cause: err });
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to set cpuset.mems on nomad cpuset cgroup: %w
- failed to write cores to nomad cpuset cgroup: %w
- failed to create share cpuset partition: %w
- failed to set cpuset.mems on share cpuset partition: %w
- failed to create reserve cpuset partition: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/036f495ed7c596da.
Report an issue: GitHub.