{"record":{"id":"4547412ede57d468","repo":"hashicorp/nomad","slug":"port-must-be-d-but-found-d","errorCode":null,"errorMessage":"port must be < %d but found %d","messagePattern":"port must be < (.+?) but found (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/funcs.go","lineNumber":518,"sourceCode":"\tports := []uint64{}\n\tfor _, part := range parts {\n\t\tpart = strings.TrimSpace(part)\n\t\trangeParts := strings.Split(part, \"-\")\n\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}","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/funcs.go#L500-L536","documentation":"ParsePortRanges rejects port numbers above MaxValidPort (65535): the segment parsed as an unsigned integer but exceeds the maximum valid TCP/UDP port. Nomad enforces the standard port bound when validating reserved port lists.","triggerScenarios":"ParsePortRanges sees a single port (or range endpoint) where port > MaxValidPort, e.g. \"80800\"; raised from node registration validation via SetNode/IsValidConfig.","commonSituations":"Typos with an extra digit (6553 -> 65535 -> 655350); decimal/octal confusion from scripts; concatenation bugs where a port string got two numbers glued together.","solutions":["Correct the port to be <= 65535","Fix any script/variable interpolation that concatenates digits into the port value","For ranges, ensure both endpoints are within 1-65535 (e.g. \"60000-65535\")","Pre-validate with structs.ParsePortRanges(input) and strconv bounds before writing client config"],"exampleFix":"// before\nreserved { ports = \"655350\" }\n// after\nreserved { ports = \"65535\" }","handlingStrategy":"validation","validationCode":"// go: enforce the 1-65535 bound before parsing\nif v, err := strconv.ParseUint(portSpec, 10, 32); err == nil && v > 65535 {\n    return fmt.Errorf(\"port %d exceeds maximum 65535\", v)\n}","typeGuard":null,"tryCatchPattern":"if _, err := structs.ParsePortRanges(portSpec); err != nil {\n    if strings.Contains(err.Error(), fmt.Sprintf(\"port must be < %d\", structs.MaxValidPort)) {\n        return fmt.Errorf(\"port out of range in %q\", portSpec)\n    }\n    return err\n}","preventionTips":["Parse ports into uint16-typed values so oversize values fail early","Check generated strings for digit concatenation bugs","Validate ranges: both endpoints in 1-65535 with start <= end"],"tags":["nomad","ports","validation","config"],"backgroundTag":"invalid-port-range","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"}