hashicorp/nomad · error
MemoryMaxMB value (%d) should be larger than MemoryMB value
Error message
MemoryMaxMB value (%d) should be larger than MemoryMB value (%d)
What it means
Nomad's Resources.Validate() rejects a task resource block where memory_max (MemoryMaxMB) is set but lower than memory (MemoryMB). memory_max is a hard ceiling for memory and must be >= the soft limit; 0 (unset) and -1 (MemoryNoLimit sentinel) are allowed exceptions. This keeps resource specifications internally consistent so the scheduler and cgroup limits are sane.
Source
Thrown at nomad/structs/structs.go:2466
// Ensure each numa bound device matches a device requested for task
if r.NUMA != nil {
for _, numaDevice := range r.NUMA.Devices {
if !devices.Contains(numaDevice) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("numa device %q not requested as task resource", numaDevice))
}
}
}
// Ensure the numa block is valid
if err := r.NUMA.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, err)
}
// Ensure memory_max is greater than memory, unless it is set to 0 or -1 which
// are both sentinel values
if (r.MemoryMaxMB != 0 && r.MemoryMaxMB != MemoryNoLimit) && r.MemoryMaxMB < r.MemoryMB {
mErr.Errors = append(mErr.Errors, fmt.Errorf("MemoryMaxMB value (%d) should be larger than MemoryMB value (%d)", r.MemoryMaxMB, r.MemoryMB))
}
if r.SecretsMB > r.MemoryMB {
mErr.Errors = append(mErr.Errors, fmt.Errorf("SecretsMB value (%d) cannot be larger than MemoryMB value (%d)", r.SecretsMB, r.MemoryMB))
}
if r.SecretsMB < 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("SecretsMB value (%d) cannot be negative", r.SecretsMB))
}
return mErr.ErrorOrNil()
}
// Merge merges this resource with another resource.
// COMPAT(0.10): Remove in 0.10
func (r *Resources) Merge(other *Resources) {
if other.CPU != 0 {
r.CPU = other.CPU
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set MemoryMaxMB (memory_max) to a value greater than or equal to MemoryMB (memory)
- Remove memory_max or set it to -1 to use the MemoryNoLimit sentinel (or 0 to leave unset)
- Swap the values if you accidentally inverted memory and memory_max
Example fix
// before
resources {
memory = 512
memory_max = 256
}
// after
resources {
memory = 512
memory_max = 1024
} Defensive patterns
Strategy: validation
Validate before calling
if r.MemoryMaxMB != 0 && r.MemoryMaxMB != MemoryNoLimit && r.MemoryMaxMB < r.MemoryMB {
return fmt.Errorf("memory_max (%d) must be >= memory (%d)", r.MemoryMaxMB, r.MemoryMB)
} Type guard
func validMemoryMax(mem, memMax int) bool {
return memMax == 0 || memMax == MemoryNoLimit || memMax >= mem
} Prevention
- Always set memory_max >= memory in templates
- Default memory_max to -1 (no limit) unless you explicitly need a ceiling
- Run nomad job validate in CI before submitting jobs
When it happens
Trigger: Submitting a job (nomad job run / API jobs POST) whose task Resources has MemoryMaxMB set to a positive value smaller than MemoryMB, e.g. memory = 512, memory_max = 256.
Common situations: Hand-writing HCL/JSON job files and swapping the two values; templating memory_max from a smaller variable; editing generated job specs after downsizing memory_max; copying specs where memory_max was tuned per-environment.
Related errors
- SecretsMB value (%d) cannot be larger than MemoryMB value (%
- minimum MemoryMB value is %d; got %d
- Missing task resources
- QEMU memory assignment out of bounds
- Memory oversubscription is not enabled; Task "%v.%v" memory_
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5aa19657c7d88795.
Report an issue: GitHub.