{"record":{"id":"36f4511527781a44","repo":"slackhq/nebula","slug":"w-w","errorCode":null,"errorMessage":"%w: %w","messagePattern":"%w: %w","errorType":"exception","errorClass":"ErrIndexAllocation","httpStatus":null,"severity":"error","filePath":"handshake/machine.go","lineNumber":392,"sourceCode":"\t\treturn fmt.Errorf(\"verify cert: %w\", err)\n\t}\n\n\tm.result.RemoteCert = verified\n\tm.remoteCertSet = true\n\treturn nil\n}\n\nfunc (m *Machine) marshalOutgoing(flags msgFlags) ([]byte, error) {\n\tif !flags.expectsPayload && !flags.expectsCert {\n\t\treturn nil, nil\n\t}\n\n\tvar p Payload\n\tif flags.expectsPayload {\n\t\tif !m.indexAllocated {\n\t\t\tindex, err := m.allocIndex()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: %w\", ErrIndexAllocation, err)\n\t\t\t}\n\t\t\tm.result.LocalIndex = index\n\t\t\tm.indexAllocated = true\n\t\t}\n\n\t\tif m.result.Initiator {\n\t\t\tp.InitiatorIndex = m.result.LocalIndex\n\t\t} else {\n\t\t\tp.ResponderIndex = m.result.LocalIndex\n\t\t\tp.InitiatorIndex = m.result.RemoteIndex\n\t\t}\n\t\tp.Time = uint64(time.Now().UnixNano())\n\t}\n\tif flags.expectsCert {\n\t\tcred := m.getCred(m.myVersion)\n\t\tif cred == nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: %v\", ErrNoCredential, m.myVersion)\n\t\t}","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/handshake/machine.go#L374-L410","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Restart the Nebula process (or reload) to release leaked/stale index entries","Tune lighthouse/hostmap limits and rate limiting for handshake traffic in the config","Investigate sources of excessive handshakes (flapping NAT, scanners, misconfigured clients) and block them","Upgrade to a Nebula version with improved index cleanup/GC behavior"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := machine.marshalOutgoing(...)\nif errors.Is(err, handshake.ErrIndexAllocation) {\n\t// index space exhausted: drop the machine, shed load, and force a fresh handshake later\n\treturn nil, err\n}","preventionTips":["Enable handshake rate limiting / rps thresholds in the config to blunt floods","Restart or reload long-running lighthouses that accumulate stale index entries","Alert on rapid hostmap growth indicating leaks or scan traffic","Firewall the Nebula UDP port from the public internet where possible"],"tags":["handshake","index-allocation","resource-exhaustion"],"backgroundTag":"index-allocation-failed","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"}