hashicorp/nomad · error

no networks available

Error message

no networks available

What it means

AssignTaskNetwork (the deprecated task-level network API) initializes its error to "no networks available" and only clears it if yieldIP finds a usable node network satisfying the ask. If the node has no advertised networks (or none survive the yield loop), this error is returned. It signals the node index has no candidate IP for the task network resource.

Source

Thrown at nomad/structs/network.go:577

			return nil, fmt.Errorf("no addresses available for %s network", port.HostNetwork)
		}
		offer = append(offer, *allocPort)
		portsInOffer = append(portsInOffer, allocPort.Value)
	}

	return offer, nil
}

// AssignTaskNetwork is used to offer network resources given a
// task.resources.network ask.  If the ask cannot be satisfied, returns nil
//
// AssignTaskNetwork and task.resources.network are deprecated in favor of
// AssignPorts and group.network. AssignTaskNetwork does not support multiple
// interfaces and only uses the node's default interface. AssignPorts is the
// method that is used for group.network asks.
func (idx *NetworkIndex) AssignTaskNetwork(ask *NetworkResource) (out *NetworkResource, err error) {
	err = fmt.Errorf("no networks available")
	idx.yieldIP(func(n *NetworkResource, offerIP net.IP) (stop bool) {
		// Convert the IP to a string
		offerIPStr := offerIP.String()

		// Check if we would exceed the bandwidth cap
		availBandwidth := idx.AvailBandwidth[n.Device]
		usedBandwidth := idx.UsedBandwidth[n.Device]
		if usedBandwidth+ask.MBits > availBandwidth {
			err = fmt.Errorf("bandwidth exceeded")
			return
		}

		used := idx.UsedPorts[offerIPStr]

		// Check if any of the reserved ports are in use
		for _, port := range ask.ReservedPorts {
			// Guard against invalid port
			if port.Value < 0 || port.Value >= MaxValidPort {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a proper network block to the Nomad client config so the node advertises interfaces.
  2. Migrate from task resources.network to group network blocks and AssignPorts (AssignTaskNetwork is deprecated).
  3. Verify the node re-registered with its networks after config change (nomad node status).
  4. In tests, populate idx.Node.Networks before calling AssignTaskNetwork.

Example fix

// before (client.hcl)
client { enabled = true }
// after
client { enabled = true }
network_interface = "eth0"
# or explicit network stanza so idx.Node.Networks is populated
Defensive patterns

Strategy: try-catch

Validate before calling

idx, _ := state.NodeByID(nil, ws, nodeID)
if idx == nil || len(idx.Node.Networks) == 0 {
  return fmt.Errorf("node %s advertises no networks; fix client network config", nodeID)
}

Type guard

func nodeHasAdvertisedNetworks(n *structs.Node) bool { return n != nil && len(n.Networks) > 0 }

Try / catch

offer, err := idx.AssignTaskNetwork(ask)
if err != nil {
  if err.Error() == "no networks available" {
    // mark node ineligible or fall back to another node
  }
  return err
}

Prevention

When it happens

Trigger: Calling NetworkIndex.AssignTaskNetwork on an index whose Node has empty/nil Networks, or where every device was filtered out before an offer could be built.

Common situations: Client node registered without a network stanza; older task `resources.network` blocks placed on nodes with no advertised interfaces; tests constructing a NetworkIndex without attaching a node.

Related errors


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