hashicorp/nomad · error

malformed port map: %q -- error: %v

Error message

malformed port map: %q -- error: %v

What it means

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.

Source

Thrown at drivers/mock/driver.go:486

	d.lastMu.Unlock()

	if driverConfig.StartErr != "" {
		return nil, nil, structs.NewRecoverableError(errors.New(driverConfig.StartErr), driverConfig.StartErrRecoverable)
	}

	// Create the driver network
	net := &drivers.DriverNetwork{
		IP:            driverConfig.DriverIP,
		AutoAdvertise: driverConfig.DriverAdvertise,
	}
	if raw := driverConfig.DriverPortMap; len(raw) > 0 {
		parts := strings.Split(raw, ":")
		if len(parts) != 2 {
			return nil, nil, fmt.Errorf("malformed port map: %q", raw)
		}
		port, err := strconv.Atoi(parts[1])
		if err != nil {
			return nil, nil, fmt.Errorf("malformed port map: %q -- error: %v", raw, err)
		}
		net.PortMap = map[string]int{parts[0]: port}
	}

	killCtx, killCancel := context.WithCancel(context.Background())
	h := &taskHandle{
		taskConfig:      cfg,
		command:         driverConfig.Command,
		execCommand:     driverConfig.ExecCommand,
		pluginExitAfter: driverConfig.pluginExitAfterDuration,
		killAfter:       driverConfig.killAfterDuration,
		logger:          d.logger.With("task_name", cfg.Name),
		waitCh:          make(chan interface{}),
		killCh:          killCtx.Done(),
		kill:            killCancel,
		startedAt:       time.Now(),
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Make the second colon-separated segment a valid numeric port (0-65535), e.g. "http:8080".
  2. Check the trailing '-- error:' in the message for the exact strconv failure.
  3. Ensure the port segment is not empty or whitespace-padded.

Example fix

// before
map[string]interface{}{"DriverPortMap": "web:8O8O"}
// after
map[string]interface{}{"DriverPortMap": "web:8080"}
Defensive patterns

Strategy: validation

Validate before calling

parts := strings.Split(raw, ":")
if len(parts) != 2 {
    return fmt.Errorf("DriverPortMap must be label:port, got %q", raw)
}
if port, err := strconv.Atoi(parts[1]); err != nil || port < 0 || port > 65535 {
    return fmt.Errorf("port segment %q must be a numeric port 0-65535", parts[1])
}

Prevention

When it happens

Trigger: DriverPortMap like "http:eight" or "http:" (empty port segment) — exactly two colon-separated parts but the port half fails strconv.Atoi.

Common situations: Typos in the port number; swapping label and port ("8080:http"); template variables resolving to empty or non-numeric strings.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/21c02edb6dee7536. Report an issue: GitHub.