k3s-io/k3s · error

the interface %s is not up

Error message

the interface %s is not up

What it means

getIPFromInterface reads the interface with net.InterfaceByName, lists its addresses, then checks net.FlagUp in iface.Flags; if the bit is clear the interface is administratively down (or still coming up) and no IP is chosen from it. Surfaced through GetIPFromInterface's wrapper message.

Source

Thrown at pkg/util/net.go:279

	if err != nil {
		return "", fmt.Errorf("interface %s does not have a correct global unicast ip: %w", ifaceName, err)
	}
	logrus.Infof("Found ip %s from iface %s", ip, ifaceName)
	return ip, nil
}

// getIPFromInterface is the private function that returns de IP of an interface
func getIPFromInterface(ifaceName string) (string, error) {
	iface, err := net.InterfaceByName(ifaceName)
	if err != nil {
		return "", err
	}
	addrs, err := iface.Addrs()
	if err != nil {
		return "", err
	}
	if iface.Flags&net.FlagUp == 0 {
		return "", fmt.Errorf("the interface %s is not up", ifaceName)
	}

	globalUnicasts := []string{}
	globalUnicastsIPv6 := []string{}
	for _, addr := range addrs {
		ip, _, err := net.ParseCIDR(addr.String())
		if err != nil {
			return "", fmt.Errorf("unable to parse CIDR for interface %s: %w", iface.Name, err)
		}
		// if not IPv4 adding it on IPv6 list
		if ip.To4() == nil {
			if ip.IsGlobalUnicast() {
				globalUnicastsIPv6 = append(globalUnicastsIPv6, ip.String())
			}
			continue
		}
		if ip.IsGlobalUnicast() {
			globalUnicasts = append(globalUnicasts, ip.String())

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Bring it up: ip link set <iface> up (and persist via your network manager, e.g. nmcli connection up)
  2. If physical, check cable/switch/port; if virtual, attach/activate the device
  3. If the link legitimately comes up later, order the service after network-online.target or add a readiness wait
  4. Point the config at a different interface that is already up, if this one is optional

Example fix

# before
ip link show eth1   # state DOWN
# after
ip link set eth1 up && dhclient eth1   # or: nmcli connection up eth1
Defensive patterns

Strategy: validation

Validate before calling

func ifaceUp(name string) bool {
	iface, err := net.InterfaceByName(name)
	return err == nil && iface.Flags&net.FlagUp != 0
}

// before deriving an IP:
if !ifaceUp(cfg.Iface) {
	return fmt.Errorf("interface %s is not up; run 'ip link set %s up'", cfg.Iface, cfg.Iface)
}

Try / catch

ip, err := util.GetIPFromInterface(name)
if err != nil && strings.Contains(err.Error(), "is not up") {
	// bring the link up or wait for it, then retry once
	if exec.Command("ip", "link", "set", name, "up").Run() == nil {
		ip, err = util.GetIPFromInterface(name)
	}
}
if err != nil {
	return "", err
}

Prevention

When it happens

Trigger: The configured interface exists but is DOWN in ip link (state down, <NO-CARRIER,DOWN>): never activated, no carrier, or a tunnel/wireguard-style device that was never brought up.

Common situations: Cloud VM with an unattached NIC; interface left down after network config changes; DHCP/network-manager not started; race at boot where the service reads config before the link is up.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/0728d94b3611dc76. Report an issue: GitHub.