{"record":{"id":"21c02edb6dee7536","repo":"hashicorp/nomad","slug":"malformed-port-map-q-error-v","errorCode":null,"errorMessage":"malformed port map: %q -- error: %v","messagePattern":"malformed port map: %q -- error: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/mock/driver.go","lineNumber":486,"sourceCode":"\td.lastMu.Unlock()\n\n\tif driverConfig.StartErr != \"\" {\n\t\treturn nil, nil, structs.NewRecoverableError(errors.New(driverConfig.StartErr), driverConfig.StartErrRecoverable)\n\t}\n\n\t// Create the driver network\n\tnet := &drivers.DriverNetwork{\n\t\tIP:            driverConfig.DriverIP,\n\t\tAutoAdvertise: driverConfig.DriverAdvertise,\n\t}\n\tif raw := driverConfig.DriverPortMap; len(raw) > 0 {\n\t\tparts := strings.Split(raw, \":\")\n\t\tif len(parts) != 2 {\n\t\t\treturn nil, nil, fmt.Errorf(\"malformed port map: %q\", raw)\n\t\t}\n\t\tport, err := strconv.Atoi(parts[1])\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"malformed port map: %q -- error: %v\", raw, err)\n\t\t}\n\t\tnet.PortMap = map[string]int{parts[0]: port}\n\t}\n\n\tkillCtx, killCancel := context.WithCancel(context.Background())\n\th := &taskHandle{\n\t\ttaskConfig:      cfg,\n\t\tcommand:         driverConfig.Command,\n\t\texecCommand:     driverConfig.ExecCommand,\n\t\tpluginExitAfter: driverConfig.pluginExitAfterDuration,\n\t\tkillAfter:       driverConfig.killAfterDuration,\n\t\tlogger:          d.logger.With(\"task_name\", cfg.Name),\n\t\twaitCh:          make(chan interface{}),\n\t\tkillCh:          killCtx.Done(),\n\t\tkill:            killCancel,\n\t\tstartedAt:       time.Now(),\n\t}\n","sourceCodeStart":468,"sourceCodeEnd":504,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/mock/driver.go#L468-L504","documentation":"After splitting DriverPortMap on \":\", StartTask parses the second segment as an integer port with strconv.Atoi. If that segment is not a number, the port map is rejected with this error including the underlying parse error.","triggerScenarios":"DriverPortMap like \"http:eight\" or \"http:\" (empty port segment) — exactly two colon-separated parts but the port half fails strconv.Atoi.","commonSituations":"Typos in the port number; swapping label and port (\"8080:http\"); template variables resolving to empty or non-numeric strings.","solutions":["Make the second colon-separated segment a valid numeric port (0-65535), e.g. \"http:8080\".","Check the trailing '-- error:' in the message for the exact strconv failure.","Ensure the port segment is not empty or whitespace-padded."],"exampleFix":"// before\nmap[string]interface{}{\"DriverPortMap\": \"web:8O8O\"}\n// after\nmap[string]interface{}{\"DriverPortMap\": \"web:8080\"}","handlingStrategy":"validation","validationCode":"parts := strings.Split(raw, \":\")\nif len(parts) != 2 {\n    return fmt.Errorf(\"DriverPortMap must be label:port, got %q\", raw)\n}\nif port, err := strconv.Atoi(parts[1]); err != nil || port < 0 || port > 65535 {\n    return fmt.Errorf(\"port segment %q must be a numeric port 0-65535\", parts[1])\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm the port half parses as an integer within 0-65535 before starting the task.","Watch for letter/digit lookalikes (O vs 0) in hand-edited configs."],"tags":["nomad","mock-driver","config","port-mapping"],"backgroundTag":"malformed-port-map","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"}