{"record":{"id":"542d710ecf3bab95","repo":"hashicorp/nomad","slug":"malformed-ulimit-specification-v-q-cannot-be-e","errorCode":null,"errorMessage":"Malformed ulimit specification %v: %q, cannot be empty","messagePattern":"Malformed ulimit specification (.+?): %q, cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/docker/driver.go","lineNumber":2122,"sourceCode":"\t\t\t}\n\t\t}\n\t} else {\n\t\td.logger.Debug(\"using client connection initialized from environment\")\n\t\tnewClient, err = mclient.New(append(opts, mclient.FromEnv)...)\n\t\tif err != nil {\n\t\t\tmerr.Errors = append(merr.Errors, err)\n\t\t}\n\t}\n\n\treturn newClient, merr.ErrorOrNil()\n}\n\nfunc sliceMergeUlimit(ulimitsRaw map[string]string) ([]*containerapi.Ulimit, error) {\n\tvar ulimits []*containerapi.Ulimit\n\n\tfor name, ulimitRaw := range ulimitsRaw {\n\t\tif len(ulimitRaw) == 0 {\n\t\t\treturn []*containerapi.Ulimit{}, fmt.Errorf(\"Malformed ulimit specification %v: %q, cannot be empty\", name, ulimitRaw)\n\t\t}\n\t\t// hard limit is optional\n\t\tif !strings.Contains(ulimitRaw, \":\") {\n\t\t\tulimitRaw = ulimitRaw + \":\" + ulimitRaw\n\t\t}\n\n\t\tsplitted := strings.SplitN(ulimitRaw, \":\", 2)\n\t\tif len(splitted) < 2 {\n\t\t\treturn []*containerapi.Ulimit{}, fmt.Errorf(\"Malformed ulimit specification %v: %v\", name, ulimitRaw)\n\t\t}\n\t\tsoft, err := strconv.Atoi(splitted[0])\n\t\tif err != nil {\n\t\t\treturn []*containerapi.Ulimit{}, fmt.Errorf(\"Malformed soft ulimit %v: %v\", name, ulimitRaw)\n\t\t}\n\t\thard, err := strconv.Atoi(splitted[1])\n\t\tif err != nil {\n\t\t\treturn []*containerapi.Ulimit{}, fmt.Errorf(\"Malformed hard ulimit %v: %v\", name, ulimitRaw)\n\t\t}","sourceCodeStart":2104,"sourceCodeEnd":2140,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/docker/driver.go#L2104-L2140","documentation":"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.","triggerScenarios":"Docker task config containing an entry like ulimits = { \"nofile\" = \"\" } — key present but value empty.","commonSituations":"Variable interpolation that expanded to empty (unset variable); copy-paste leaving a value blank; templating logic writing the key without a value.","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."],"exampleFix":"// before\nulimits = { nofile = \"\" }\n// after\nulimits = { nofile = \"4096:8192\" }","handlingStrategy":"validation","validationCode":"for name, val := range cfg.Ulimits {\n    if strings.TrimSpace(val) == \"\" {\n        return fmt.Errorf(\"ulimit %q has empty value\", name)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["docker","ulimit","config-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}