{"record":{"id":"d4fca1cd0fee8493","repo":"hashicorp/nomad","slug":"maximum-of-d-ports-can-be-reserved","errorCode":null,"errorMessage":"maximum of %d ports can be reserved","messagePattern":"maximum of (.+?) ports can be reserved","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/funcs.go","lineNumber":522,"sourceCode":"\t\tl := len(rangeParts)\n\t\tswitch l {\n\t\tcase 1:\n\t\t\tif val := rangeParts[0]; val == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"can't specify empty port\")\n\t\t\t} else {\n\t\t\t\tport, err := strconv.ParseUint(val, 10, 0)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tif port == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"port must be > 0\")\n\t\t\t\t}\n\t\t\t\tif port > MaxValidPort {\n\t\t\t\t\treturn nil, fmt.Errorf(\"port must be < %d but found %d\", MaxValidPort, port)\n\t\t\t\t}\n\t\t\t\tcount++\n\t\t\t\tif count > MaxValidPort {\n\t\t\t\t\treturn nil, fmt.Errorf(\"maximum of %d ports can be reserved\", MaxValidPort)\n\t\t\t\t}\n\t\t\t\tports = append(ports, port)\n\t\t\t}\n\t\tcase 2:\n\t\t\t// We are parsing a range\n\t\t\tstart, err := strconv.ParseUint(rangeParts[0], 10, 0)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tend, err := strconv.ParseUint(rangeParts[1], 10, 0)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif end < start {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid range: ending value (%v) less than starting (%v) value\", end, start)\n\t\t\t}","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/funcs.go#L504-L540","documentation":"ParsePortRanges parses a comma-separated port list/range spec (e.g. \"80,100-120\") for dynamic port reservations. While accumulating individual ports it refuses once the total count exceeds MaxValidPort, so callers cannot reserve an unbounded number of ports in one spec.","triggerScenarios":"Calling ParsePortRanges with a spec whose total number of individual ports (counting every port inside ranges) exceeds MaxValidPort (65536).","commonSituations":"Typo in a job's port block producing an enormous range like \"1-65536\" repeatedly, programmatically generated port lists, or accidentally reserving all ports in a range for a single task.","solutions":["Reduce the number of ports in the spec to 65536 or fewer","Split the reservation across multiple port blocks or tasks","Check for an off-by-one or unit typo that inflated the range"],"exampleFix":"// before\nports = \"1-65536\"\n// after\nports = \"20000-20100\"","handlingStrategy":"validation","validationCode":"func validatePortSpecCount(spec string, max int) error {\n  count := 0\n  for _, part := range strings.Split(spec, \",\") {\n    if strings.Count(part, \"-\") == 1 {\n      r := strings.Split(part, \"-\")\n      s, _ := strconv.Atoi(r[0]); e, _ := strconv.Atoi(r[1])\n      count += e - s\n    } else { count++ }\n  }\n  if count > max { return fmt.Errorf(\"spec reserves %d ports, max %d\", count, max) }\n  return nil\n}","typeGuard":null,"tryCatchPattern":"ports, err := structs.ParsePortRanges(spec)\nif err != nil {\n  return fmt.Errorf(\"invalid port spec %q: %w\", spec, err)\n}","preventionTips":["Keep reserved ranges small; prefer dynamic ports","Count range sizes before submitting large specs","Lint job files for suspiciously wide ranges"],"tags":["nomad","ports","validation"],"backgroundTag":"port-range-too-large","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"}