slackhq/nebula · error

failed to generate unique localIndexId

Error message

failed to generate unique localIndexId

What it means

AddRelay generates a random localIndexId for the relay and loops retrying if it collides with an existing index in the hostmap. If it exhausts the loop without finding a unique id, it returns this error. With random 32-bit-ish ids this practically only happens when the hostmap is saturated with indexes.

Source

Thrown at relay_manager.go:267

			hm.Relays[index] = relayHostInfo
			newRelay := Relay{
				Type:       relayType,
				State:      state,
				LocalIndex: index,
				PeerAddr:   vpnIp,
			}

			if remoteIdx != nil {
				newRelay.RemoteIndex = *remoteIdx
			}
			relayHostInfo.relayState.InsertRelay(vpnIp, index, &newRelay)

			return index, nil
		}
	}

	return 0, errors.New("failed to generate unique localIndexId")
}

// EstablishRelay updates a Requested Relay to become an Established Relay, which can pass traffic.
func (rm *relayManager) EstablishRelay(relayHostInfo *HostInfo, m *NebulaControl) (*Relay, error) {
	relay, ok := relayHostInfo.relayState.CompleteRelayByIdx(m.InitiatorRelayIndex, m.ResponderRelayIndex)
	if !ok {
		var relayFrom, relayTo any
		if m.RelayFromAddr == nil {
			relayFrom = m.OldRelayFromAddr
		} else {
			relayFrom = m.RelayFromAddr
		}
		if m.RelayToAddr == nil {
			relayTo = m.OldRelayToAddr
		} else {
			relayTo = m.RelayToAddr
		}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Reduce concurrent tunnel/relay count on the node or restart the process to clear stale hostmap indexes.
  2. Verify the RNG used for index generation is seeded correctly (crypto/rand) if indexes repeat suspiciously.
  3. Investigate leaked hostmap entries that are never cleaned up, which shrink the free index space.
Defensive patterns

Strategy: retry

Try / catch

idx, err := rm.AddRelay(hi, vpnIp, idx, nil, RelayEstablished, false)
if err != nil {
    if err.Error() == "failed to generate unique localIndexId" {
        return errors.New("hostmap index space exhausted; reduce tunnel count or restart")
    }
    return err
}

Prevention

When it happens

Trigger: The id-generation retry loop in AddRelay never finds a free localIndexId — i.e. every candidate index generated collides with an existing hostmap/relay entry across all attempts.

Common situations: Host with an extremely large number of concurrent tunnels/relays exhausting the index space; a bug or entropy problem making generated indexes non-random; test harnesses pre-filling the index space.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/9abacd012912dae7. Report an issue: GitHub.