hashicorp/nomad · error
error parsing port %q from service %q: %v
Error message
error parsing port %q from service %q: %v
What it means
Immediately after successfully splitting the PortLabel, the port component must parse as an integer via strconv.Atoi. If the port substring is non-numeric (bad interpolation, garbage in the label), this error is returned with the raw port, service name, and underlying error.
Source
Thrown at command/agent/consul/service_client.go:1229
//
// Note: no need to manually plumb Consul namespace into the agent service registration
// or its check registrations, because the Nomad Client's Consul Client will already
// have the Nomad Client's Consul Namespace set on startup.
func (c *ServiceClient) RegisterAgent(role string, services []*structs.Service) error {
ops := operations{}
for _, service := range services {
id := makeAgentServiceID(role, service)
// Unlike tasks, agents don't use port labels. Agent ports are
// stored directly in the PortLabel.
host, rawport, err := net.SplitHostPort(service.PortLabel)
if err != nil {
return fmt.Errorf("error parsing port label %q from service %q: %v", service.PortLabel, service.Name, err)
}
port, err := strconv.Atoi(rawport)
if err != nil {
return fmt.Errorf("error parsing port %q from service %q: %v", rawport, service.Name, err)
}
serviceReg := &api.AgentServiceRegistration{
ID: id,
Name: service.Name,
Tags: service.Tags,
Address: host,
Port: port,
// This enables the consul UI to show that Nomad registered this service
Meta: map[string]string{
"external-source": "nomad",
},
}
ops.regServices = append(ops.regServices, serviceReg)
// older agents use SHA-1 hashes as part of the service name instead of
// SHA-256, but we can't guarantee they've shutdown gracefully and
// deregistered themselves on upgrade. Remove any legacy service IDs
// that might be lingeringView on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the interpolated port variable (e.g. ${NOMAD_PORT_http}) refers to a numeric, allocated port.
- Fix or remove malformed characters in the PortLabel so the port segment is a plain integer.
- Validate the job spec and inspect the rendered template to confirm resolved values.
Example fix
// before
port = "${NOMAD_HOST_IP_http}:${NOMAD_PORT_name}" // wrong var -> non-numeric port
// after
port = "${NOMAD_IP_http}:${NOMAD_PORT_http}" Defensive patterns
Strategy: validation
Validate before calling
_, rawport, err := net.SplitHostPort(label)
if err != nil { return err }
if _, err := strconv.Atoi(rawport); err != nil {
return fmt.Errorf("port %q is not numeric", rawport)
} Type guard
func isNumericPort(raw string) bool {
p, err := strconv.Atoi(raw)
return err == nil && p > 0 && p < 65536
} Prevention
- Use ${NOMAD_PORT_*} interpolation pointing at numeric ports.
- Avoid hand-writing address:port strings in job specs.
- Validate rendered job values before registration.
When it happens
Trigger: service.PortLabel contains a host:port whose port field is not a valid integer — e.g. unresolved '${...}' leftovers, letters, or a trailing colon producing an empty rawport.
Common situations: Malformed NOMAD_PORT_* interpolation, jobs where the port variable resolves to a name rather than a number, hand-written address:port strings with typos.
Related errors
- error parsing port label %q from service %q: %v
- service %q contains invalid check: agent checks do not suppo
- error parsing port %q from check %q: %v
- error creating bootstrap configuration for Connect proxy sid
- no default Consul services client
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4583bd0670beee21.
Report an issue: GitHub.