hashicorp/nomad · error
Malformed ulimit specification %v: %q, cannot be empty
Error message
Malformed ulimit specification %v: %q, cannot be empty
What it means
sliceMergeUlimit converts the driver's `ulimit` config map (name -> "soft[:hard]") into Docker Ulimit structs. If a value is an empty string, the driver cannot build any limit and returns this error naming the ulimit key. It is a config-parsing failure raised before any container is created.
Source
Thrown at drivers/docker/driver.go:2122
}
}
} else {
d.logger.Debug("using client connection initialized from environment")
newClient, err = mclient.New(append(opts, mclient.FromEnv)...)
if err != nil {
merr.Errors = append(merr.Errors, err)
}
}
return newClient, merr.ErrorOrNil()
}
func sliceMergeUlimit(ulimitsRaw map[string]string) ([]*containerapi.Ulimit, error) {
var ulimits []*containerapi.Ulimit
for name, ulimitRaw := range ulimitsRaw {
if len(ulimitRaw) == 0 {
return []*containerapi.Ulimit{}, fmt.Errorf("Malformed ulimit specification %v: %q, cannot be empty", name, ulimitRaw)
}
// hard limit is optional
if !strings.Contains(ulimitRaw, ":") {
ulimitRaw = ulimitRaw + ":" + ulimitRaw
}
splitted := strings.SplitN(ulimitRaw, ":", 2)
if len(splitted) < 2 {
return []*containerapi.Ulimit{}, fmt.Errorf("Malformed ulimit specification %v: %v", name, ulimitRaw)
}
soft, err := strconv.Atoi(splitted[0])
if err != nil {
return []*containerapi.Ulimit{}, fmt.Errorf("Malformed soft ulimit %v: %v", name, ulimitRaw)
}
hard, err := strconv.Atoi(splitted[1])
if err != nil {
return []*containerapi.Ulimit{}, fmt.Errorf("Malformed hard ulimit %v: %v", name, ulimitRaw)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Provide a value for every ulimit key, e.g. ulimits = { nofile = "1024:4096" } or soft-only "1024".
- Remove the empty key from the map if the ulimit isn't needed.
- Fix upstream interpolation/templating so the value isn't blank.
- Validate ulimit entries in CI before submitting the job.
Example fix
// before
ulimits = { nofile = "" }
// after
ulimits = { nofile = "4096:8192" } Defensive patterns
Strategy: validation
Validate before calling
for name, val := range cfg.Ulimits {
if strings.TrimSpace(val) == "" {
return fmt.Errorf("ulimit %q has empty value", name)
}
} Prevention
- Always supply "soft" or "soft:hard" for each ulimit key.
- Delete unused ulimit keys instead of leaving them empty.
- Verify variable interpolation produced non-empty values in CI.
When it happens
Trigger: Docker task config containing an entry like ulimits = { "nofile" = "" } — key present but value empty.
Common situations: Variable interpolation that expanded to empty (unset variable); copy-paste leaving a value blank; templating logic writing the key without a value.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse ulimit configuration: %v
- Malformed ulimit specification %v: %v
- Malformed soft ulimit %v: %v
- host path must be set in configuration for devices
- invalid value for cpu_cfs_period
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/542d710ecf3bab95.
Report an issue: GitHub.