{"record":{"id":"770bc18b544bf18b","repo":"slackhq/nebula","slug":"errinitiatealreadycalled","errorCode":"ErrInitiateAlreadyCalled","errorMessage":"initiate already called","messagePattern":"initiate already called","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"handshake/errors.go","lineNumber":7,"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":"ErrInitiateAlreadyCalled is returned when Machine.Initiate is invoked a second time. The Noise handshake state must be at message index 0 to initiate; once Initiate has run, the handshake is in progress and cannot be re-initiated.","triggerScenarios":"Calling Machine.Initiate more than once on the same machine — detected via m.hs.MessageIndex() != 0 in handshake/machine.go:177 — typically on retry logic that reuses the machine instead of rebuilding it.","commonSituations":"Retry loops that call Initiate again after a failed or timed-out handshake using the same Machine; reconnect logic reusing a machine whose handshake already started.","solutions":["Create a fresh Machine for each handshake attempt instead of reusing one.","Only call Initiate once per Machine; resume an in-progress handshake with ProcessPacket.","Guard the call site: check MessageIndex()==0 or a local 'initiated' flag before calling Initiate."],"exampleFix":"// before\nif err != nil {\n    packet, err = m.Initiate(nil) // reuse after failure\n}\n// after\nif err != nil {\n    m = handshake.NewMachine(cs, true) // fresh machine per attempt\n    packet, err = m.Initiate(nil)\n}","handlingStrategy":"try-catch","validationCode":"if m.hs != nil && m.hs.MessageIndex() != 0 {\n    return errors.New(\"handshake already initiated\")\n}","typeGuard":"func canCallInitiate(m *handshake.Machine) bool {\n    return m.Result().Initiator && !m.Failed()\n}","tryCatchPattern":"packet, err := m.Initiate(payload)\nif errors.Is(err, handshake.ErrInitiateAlreadyCalled) {\n    // reuse existing handshake state; do not retry Initiate\n    return nil\n}","preventionTips":["Create a new Machine per handshake attempt","Never call Initiate inside retry loops on a reused machine","Track an 'initiated' boolean at the call site","After a failed handshake, rebuild the machine from scratch"],"tags":["handshake","state-machine","retry"],"backgroundTag":"invalid-state-transition","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"}