{"record":{"id":"b3947a73acf34ddc","repo":"slackhq/nebula","slug":"errindexallocation","errorCode":"ErrIndexAllocation","errorMessage":"failed to allocate local index","messagePattern":"failed to allocate local index","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"handshake/errors.go","lineNumber":17,"sourceCode":"package handshake\n\nimport \"errors\"\n\nvar (\n\tErrInitiateOnResponder     = errors.New(\"initiate called on responder\")\n\tErrInitiateAlreadyCalled   = errors.New(\"initiate already called\")\n\tErrInitiateNotCalled       = errors.New(\"initiate must be called before ProcessPacket for initiators\")\n\tErrPacketTooShort          = errors.New(\"packet too short\")\n\tErrPublicKeyMismatch       = errors.New(\"public key mismatch between certificate and handshake\")\n\tErrIncompleteHandshake     = errors.New(\"handshake completed without receiving required content\")\n\tErrMachineFailed           = errors.New(\"handshake machine has failed\")\n\tErrUnknownSubtype          = errors.New(\"unknown handshake subtype\")\n\tErrMissingContent          = errors.New(\"expected handshake content but message was empty\")\n\tErrUnexpectedContent       = errors.New(\"received unexpected handshake content\")\n\tErrInvalidRemoteIndex      = errors.New(\"peer sent an invalid index in handshake payload\")\n\tErrIndexAllocation         = errors.New(\"failed to allocate local index\")\n\tErrNoCredential            = errors.New(\"no handshake credential available for cert version\")\n\tErrAsymmetricCipherKeys    = errors.New(\"noise produced only one cipher key\")\n\tErrMultiMessageUnsupported = errors.New(\"multi-message handshake patterns are not yet supported by the manager\")\n\tErrSubtypeMismatch         = errors.New(\"packet subtype does not match handshake machine subtype\")\n)\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/handshake/errors.go#L1-L23","documentation":"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.","triggerScenarios":"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>\".","commonSituations":"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.","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"],"exampleFix":"// before: connections torn down without freeing indexes\nconn.Close()\n\n// after\nidx := conn.Index()\nconn.Close()\nindexMgr.Free(idx) // return the index to the pool","handlingStrategy":"fallback","validationCode":"if indexMgr.Remaining() == 0 {\n    return errors.New(\"index pool exhausted; free indexes before handshaking\")\n}","typeGuard":"func allocatorHealthy(mgr *index.Manager) bool {\n    return mgr != nil && !mgr.Closed() && mgr.Remaining() > 0\n}","tryCatchPattern":"res, err := m.ProcessPacket(out, pkt)\nvar idxErr *fs.PathError\nif errors.Is(err, handshake.ErrIndexAllocation) {\n    // free stale indexes and retry after backoff\n    indexMgr.FreeStale(idleTimeout)\n    time.AfterFunc(backoff, func() { retryHandshake(conn) })\n    return\n}","preventionTips":["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"],"tags":["handshake","resources","index-allocation"],"backgroundTag":"resource-exhaustion","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}