slackhq/nebula · error
ErrIndexAllocation
ErrIndexAllocation
Error message
failed to allocate local index
What it means
ErrIndexAllocation is returned by marshalOutgoing when the machine's index allocator (m.allocIndex) fails while trying to obtain a local index for the outgoing handshake message. The original allocator error is wrapped alongside it with fmt.Errorf("%w: %w", ...) so both causes are matchable with errors.Is. It signals the local node could not reserve a connection index, typically due to resource exhaustion.
Source
Thrown at handshake/errors.go:17
package handshake
import "errors"
var (
ErrInitiateOnResponder = errors.New("initiate called on responder")
ErrInitiateAlreadyCalled = errors.New("initiate already called")
ErrInitiateNotCalled = errors.New("initiate must be called before ProcessPacket for initiators")
ErrPacketTooShort = errors.New("packet too short")
ErrPublicKeyMismatch = errors.New("public key mismatch between certificate and handshake")
ErrIncompleteHandshake = errors.New("handshake completed without receiving required content")
ErrMachineFailed = errors.New("handshake machine has failed")
ErrUnknownSubtype = errors.New("unknown handshake subtype")
ErrMissingContent = errors.New("expected handshake content but message was empty")
ErrUnexpectedContent = errors.New("received unexpected handshake content")
ErrInvalidRemoteIndex = errors.New("peer sent an invalid index in handshake payload")
ErrIndexAllocation = errors.New("failed to allocate local index")
ErrNoCredential = errors.New("no handshake credential available for cert version")
ErrAsymmetricCipherKeys = errors.New("noise produced only one cipher key")
ErrMultiMessageUnsupported = errors.New("multi-message handshake patterns are not yet supported by the manager")
ErrSubtypeMismatch = errors.New("packet subtype does not match handshake machine subtype")
)
View on GitHub (pinned to dd8f660c0a)
Solutions
- Release/free stale indexes when connections close so the allocator has capacity
- Inspect the wrapped cause with errors.Is/As to find the underlying allocator failure
- Increase the index pool size / max connection limit, or restart the node to reclaim leaked indexes
- Delay handshakes during shutdown when the allocator is closed
Example fix
// before: connections torn down without freeing indexes conn.Close() // after idx := conn.Index() conn.Close() indexMgr.Free(idx) // return the index to the pool
Defensive patterns
Strategy: fallback
Validate before calling
if indexMgr.Remaining() == 0 {
return errors.New("index pool exhausted; free indexes before handshaking")
} Type guard
func allocatorHealthy(mgr *index.Manager) bool {
return mgr != nil && !mgr.Closed() && mgr.Remaining() > 0
} Try / catch
res, err := m.ProcessPacket(out, pkt)
var idxErr *fs.PathError
if errors.Is(err, handshake.ErrIndexAllocation) {
// free stale indexes and retry after backoff
indexMgr.FreeStale(idleTimeout)
time.AfterFunc(backoff, func() { retryHandshake(conn) })
return
} Prevention
- Free indexes deterministically when connections close (defer indexMgr.Free(idx))
- Alert when index pool utilization exceeds a threshold
- Stop accepting new handshakes gracefully during shutdown
When it happens
Trigger: marshalOutgoing at handshake/machine.go:392 calls m.allocIndex() which returns an error (e.g. index table full or allocator closed), producing "failed to allocate local index: <cause>".
Common situations: Long-lived node exhausting its index space because old indexes are never released; allocator shut down during node shutdown while handshakes are still in flight; hitting a configured max-connections limit.
Related errors
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/b3947a73acf34ddc.
Report an issue: GitHub.