lima-vm/lima · error

usernet unable to resolve IP for SSH forwarding

Error message

usernet unable to resolve IP for SSH forwarding

What it means

Lima's usernet client polled the usernet DHCP leases endpoint every 500ms for the full resolve timeout (default 2 minutes, configurable via LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT) without ever seeing a lease whose MAC address matches the VM's MAC address, so it cannot determine the guest IP for SSH port forwarding.

Source

Thrown at pkg/networks/usernet/client.go:101

	}
	return nil
}

func (c *Client) ResolveIPAddress(ctx context.Context, vmMacAddr string) (string, error) {
	resolveIPAddressTimeout := 2 * time.Minute
	resolveIPAddressTimeoutEnv := os.Getenv("LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT")
	if resolveIPAddressTimeoutEnv != "" {
		if parsedTimeout, err := strconv.Atoi(resolveIPAddressTimeoutEnv); err == nil {
			resolveIPAddressTimeout = time.Duration(parsedTimeout) * time.Minute
		}
	}
	ctx, cancel := context.WithTimeout(ctx, resolveIPAddressTimeout)
	defer cancel()
	ticker := time.NewTicker(500 * time.Millisecond)
	for {
		select {
		case <-ctx.Done():
			return "", errors.New("usernet unable to resolve IP for SSH forwarding")
		case <-ticker.C:
			leases, err := c.Leases(ctx)
			if err != nil {
				return "", err
			}

			for ipAddr, leaseAddr := range leases {
				if vmMacAddr == leaseAddr {
					return ipAddr, nil
				}
			}
		}
	}
}

func (c *Client) Leases(ctx context.Context) (map[string]string, error) {
	u := fmt.Sprintf("%s%s", c.base, "/services/dhcp/leases")
	res, err := httpclientutil.Get(ctx, c.client, u)

View on GitHub (pinned to dd909d0973)

Solutions

  1. Increase the timeout: export LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT=5 (minutes) and retry
  2. Check the guest actually booted and requested DHCP (limactl shell <instance>; ip link / dhclient), inspect limactl logs
  3. Verify the VM's MAC address matches what usernet leases report; restart the instance to re-trigger DHCP
  4. Recreate the instance if its network state is wedged: limactl delete <instance> && limactl start <template>

Example fix

// before
limactl start  # times out after 2 min resolving IP
// after
export LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT=5
limactl start
Defensive patterns

Strategy: retry

Validate before calling

// raise the resolve window before starting slow-booting guests
os.Setenv("LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT", "5") // minutes

Try / catch

ip, err := client.ResolveIPAddress(ctx, macAddr)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "unable to resolve IP") {
        // retry with longer timeout, or verify the guest booted & DHCP ran
    }
}

Prevention

When it happens

Trigger: ResolveIPAddress (via ConfigureDriver or WaitOpeningSSHPort) polls c.Leases(ctx) until ctx.Done() fires with no matching MAC — the VM never obtained a DHCP lease on the usernet network, or the MAC address doesn't match the lease entries.

Common situations: Guest failed to boot or to run DHCP, the instance's MAC address changed vs. recorded leases, usernet's DHCP server not assigning leases (broken vde/udpvmnet backend), or slow guests exceeding the 2-minute default timeout (fixable by raising LIMA_USERNET_RESOLVE_IP_ADDRESS_TIMEOUT).

Related errors


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/16b76c7c7f3a598f. Report an issue: GitHub.