slackhq/nebula · error · ErrIndexAllocation

%w: %w

Error message

%w: %w

What it means

marshalOutgoing wraps ErrIndexAllocation together with the underlying error when allocating a remote index for the handshake response fails (m.allocIndex). Nebula tracks handshake message indices in a bounded hostmap; allocation fails when the index space is exhausted or the underlying hostmap insertion errors (e.g. duplicate/colliding index, out of memory for a new map slot).

Source

Thrown at handshake/machine.go:392

		return fmt.Errorf("verify cert: %w", err)
	}

	m.result.RemoteCert = verified
	m.remoteCertSet = true
	return nil
}

func (m *Machine) marshalOutgoing(flags msgFlags) ([]byte, error) {
	if !flags.expectsPayload && !flags.expectsCert {
		return nil, nil
	}

	var p Payload
	if flags.expectsPayload {
		if !m.indexAllocated {
			index, err := m.allocIndex()
			if err != nil {
				return nil, fmt.Errorf("%w: %w", ErrIndexAllocation, err)
			}
			m.result.LocalIndex = index
			m.indexAllocated = true
		}

		if m.result.Initiator {
			p.InitiatorIndex = m.result.LocalIndex
		} else {
			p.ResponderIndex = m.result.LocalIndex
			p.InitiatorIndex = m.result.RemoteIndex
		}
		p.Time = uint64(time.Now().UnixNano())
	}
	if flags.expectsCert {
		cred := m.getCred(m.myVersion)
		if cred == nil {
			return nil, fmt.Errorf("%w: %v", ErrNoCredential, m.myVersion)
		}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Restart the Nebula process (or reload) to release leaked/stale index entries
  2. Tune lighthouse/hostmap limits and rate limiting for handshake traffic in the config
  3. Investigate sources of excessive handshakes (flapping NAT, scanners, misconfigured clients) and block them
  4. Upgrade to a Nebula version with improved index cleanup/GC behavior
Defensive patterns

Strategy: try-catch

Try / catch

resp, err := machine.marshalOutgoing(...)
if errors.Is(err, handshake.ErrIndexAllocation) {
	// index space exhausted: drop the machine, shed load, and force a fresh handshake later
	return nil, err
}

Prevention

When it happens

Trigger: buildResponse -> marshalOutgoing for a payload-expecting handshake stage where m.indexAllocated is false and m.allocIndex() returns an error — typically the remote index table (hostmap) is full or saturated with stale entries.

Common situations: Under sustained handshake floods / port-scan traffic exhausting the index space, leak of index entries from many short-lived connections, long uptimes without restarting lighthouses, hosts behind NAT repeatedly re-handshaking.

Related errors


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