hashicorp/nomad · error

Malformed soft ulimit %v: %v

Error message

Malformed soft ulimit %v: %v

What it means

The soft (first) component of the "soft:hard" ulimit string must be an integer; strconv.Atoi on splitted[0] failing triggers this error. The raw value is included so the developer can see the offending string. Raised during task config parsing before container creation.

Source

Thrown at drivers/docker/driver.go:2135

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)
		}

		ulimit := &containerapi.Ulimit{
			Name: name,
			Soft: int64(soft),
			Hard: int64(hard),
		}
		ulimits = append(ulimits, ulimit)
	}
	return ulimits, nil
}

func isDockerTransientError(err error) bool {
	if err == nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Use plain decimal integers: ulimits = { nofile = "1048576:1048576" }.
  2. Replace "unlimited" with -1 (Docker's convention for unlimited).
  3. Strip units/suffixes — ulimits are counts, not sizes.
  4. Validate each colon-separated part with strconv.Atoi in a pre-flight check.

Example fix

// before
ulimits = { memlock = "unlimited:unlimited" }
// after
ulimits = { memlock = "-1:-1" }
Defensive patterns

Strategy: validation

Validate before calling

parts := strings.SplitN(val, ":", 2)
if _, err := strconv.Atoi(strings.TrimSpace(parts[0])); err != nil {
    return fmt.Errorf("ulimit %q soft value %q is not an integer", name, parts[0])
}

Prevention

When it happens

Trigger: ulimit value like "abc:4096", "10_24:4096", "0x100:4096", or "1024.5:4096" where the soft part isn't a decimal integer.

Common situations: Confusing ulimits with other byte/size formats (e.g. "1gb", "unlimited"); copy-pasting Kubernetes-style quantities; typos in numeric values.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/2b43b6860b774464. Report an issue: GitHub.