{"record":{"id":"1640a4542163d954","repo":"docker/cli","slug":"invalid-range-format-for-expose-w","errorCode":null,"errorMessage":"invalid range format for --expose: %w","messagePattern":"invalid range format for --expose: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/container/opts.go","lineNumber":474,"sourceCode":"\t}\n\n\t// Add published ports as exposed ports.\n\texposedPorts := network.PortSet{}\n\tfor port := range ports {\n\t\tp, err := network.ParsePort(string(port))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texposedPorts[p] = struct{}{}\n\t}\n\n\t// Merge in exposed ports to the map of published ports\n\tfor _, e := range copts.expose.GetSlice() {\n\t\t// support two formats for expose, original format <portnum>/[<proto>]\n\t\t// or <startport-endport>/[<proto>]\n\t\tpr, err := network.ParsePortRange(e)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid range format for --expose: %w\", err)\n\t\t}\n\t\t// parse the start and end port and create a sequence of ports to expose\n\t\t// if expose a port, the start and end port are the same\n\t\tfor p := range pr.All() {\n\t\t\texposedPorts[p] = struct{}{}\n\t\t}\n\t}\n\n\t// validate and parse device mappings. Note we do late validation of the\n\t// device path (as opposed to during flag parsing), as at the time we are\n\t// parsing flags, we haven't yet sent a _ping to the daemon to determine\n\t// what operating system it is.\n\tdevices := copts.devices.GetSlice()\n\tdeviceMappings := make([]container.DeviceMapping, 0, len(devices))\n\tcdiDeviceNames := make([]string, 0, len(devices))\n\tfor _, device := range devices {\n\t\tif cdi.IsQualifiedName(device) {\n\t\t\tcdiDeviceNames = append(cdiDeviceNames, device)","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/opts.go#L456-L492","documentation":"Returned in opts.go:474 when network.ParsePortRange cannot parse a --expose token. --expose accepts either a single port[/proto] or a start-end[/proto] range; anything else fails.","triggerScenarios":"`docker run --expose <bad>`: non-numeric port, a range with the start greater than the end, a port above 65535, or malformed separators.","commonSituations":"Typo like --expose 8080..9090 (double dot), --expose 9000-8000 (reversed range), or --expose abc/tcp.","solutions":["Use the form PORT[/PROTO] or STARTPORT-ENDPORT[/PROTO].","Ensure start <= end and ports are within 0-65535.","Check for stray separators (.., --, etc.)."],"exampleFix":"# before\ndocker run --expose 8080..9090 alpine\n\n# after\ndocker run --expose 8080-9090 alpine","handlingStrategy":"validation","validationCode":"import \"github.com/docker/docker/api/types/network\"\nif _, err := network.ParsePortRange(expose); err != nil {\n    return fmt.Errorf(\"bad --expose %q: %w\", expose, err)\n}","typeGuard":"func validPortRange(s string) bool {\n    _, err := network.ParsePortRange(s)\n    return err == nil\n}","tryCatchPattern":"// Deterministic: fix the token; do not retry.\nif !validPortRange(tok) { /* drop or correct the token */ }","preventionTips":["Use PORT or START-END forms with optional /proto.\nEnsure start<=end and ports<=65535.\nValidate ranges in generated commands."],"tags":["container","network","ports","flag-validation","create"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}