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

  1. Provide a value for every ulimit key, e.g. ulimits = { nofile = "1024:4096" } or soft-only "1024".
  2. Remove the empty key from the map if the ulimit isn't needed.
  3. Fix upstream interpolation/templating so the value isn't blank.
  4. 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

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.

Related errors


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