slackhq/nebula · error
ErrInvalidRemoteIndex
ErrInvalidRemoteIndex
Error message
peer sent an invalid index in handshake payload
What it means
ErrInvalidRemoteIndex is returned by processPayload when the peer's handshake payload carries a remote index of 0, which is not a valid allocated index in this protocol. Index 0 is reserved/invalid, so receiving it indicates a malformed payload from the peer; the machine is marked failed and the result's RemoteIndex stays zero.
Source
Thrown at handshake/errors.go:16
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
- Fix the peer so it allocates a nonzero local index before marshaling its payload
- Ensure the peer's index allocator is initialized and healthy (check its logs for allocation errors)
- Retry the handshake; if repeated, drop connections from that peer as potentially hostile
Example fix
// before
p := handshake.Payload{Time: now} // InitiatorIndex defaults to 0
// after
idx, err := indexMgr.Alloc()
if err != nil { return err }
p := handshake.Payload{InitiatorIndex: idx, Time: now} Defensive patterns
Strategy: validation
Validate before calling
p := handshake.Payload{InitiatorIndex: myIndex, Time: now}
if p.InitiatorIndex == 0 {
return errors.New("refusing to send payload with zero index")
} Type guard
func validRemoteIndex(p handshake.Payload) bool {
return p.InitiatorIndex != 0
} Try / catch
res, err := m.ProcessPacket(out, pkt)
if errors.Is(err, handshake.ErrInvalidRemoteIndex) {
// peer's allocator is broken or packet is hostile
conn.Close()
metrics.Inc("handshake_invalid_index")
return
} Prevention
- Always allocate a nonzero index before marshaling handshake payloads
- Check allocator health before initiating handshakes
- Drop repeated offenders: zero-index payloads indicate buggy or hostile peers
When it happens
Trigger: processPayload parses the Payload and remoteIndex == 0 at handshake/machine.go:325; reproduced in machine_test.go:237 with Payload{InitiatorIndex: 0, Time: 1}.
Common situations: Peer failed to allocate an index before sending (its own allocator errored); uninitialized Payload struct marshaled without setting the index field; crafted/malformed packets from a non-peer host.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/1042d75667d26a89.
Report an issue: GitHub.