{"record":{"id":"f1f00d5f4cc65d70","repo":"slackhq/nebula","slug":"errmachinefailed","errorCode":"ErrMachineFailed","errorMessage":"handshake machine has failed","messagePattern":"handshake machine has failed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"handshake/errors.go","lineNumber":12,"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":"ErrMachineFailed is returned by Initiate and ProcessPacket when the handshake Machine has already entered a failed state from a previous error (every failure path sets m.failed = true). Once failed, the machine is permanently unusable by design; the caller must construct a new Machine. This guards against using a machine with corrupted or inconsistent handshake state.","triggerScenarios":"Calling m.Initiate(out) or m.ProcessPacket(out, packet) after any earlier call on the same Machine returned an error that set m.failed (e.g. ErrPublicKeyMismatch, ErrMissingContent, ErrSubtypeMismatch).","commonSituations":"Reusing a Machine object across retry loops after a failed handshake; a caller ignoring the first error and continuing to feed packets into the dead machine.","solutions":["Check m.Failed() before reuse and construct a new Machine via NewMachine when true","Handle the original error that failed the machine (fix keys/certs/network) before retrying","Never share one Machine across goroutines or handshake attempts; one machine per handshake"],"exampleFix":"// before\nres, err := m.ProcessPacket(out, pkt)\nif err != nil {\n    res, err = m.ProcessPacket(out, pkt) // ErrMachineFailed\n}\n\n// after\nres, err := m.ProcessPacket(out, pkt)\nif err != nil {\n    m, err = handshake.NewMachine(cs, version, getCred) // fresh machine\n    res, err = m.ProcessPacket(out, pkt)\n}","handlingStrategy":"type-guard","validationCode":"if m.Failed() {\n    return errors.New(\"handshake machine failed; create a new one\")\n}","typeGuard":"func machineUsable(m *handshake.Machine) bool {\n    return m != nil && !m.Failed()\n}","tryCatchPattern":"res, err := m.ProcessPacket(out, pkt)\nif errors.Is(err, handshake.ErrMachineFailed) {\n    // machine is dead by design: never retry on it, recreate\n    m = newHandshakeMachine()\n}","preventionTips":["Check Failed() before every reuse of a Machine","One Machine per handshake attempt; discard on first error","Log the first error that failed the machine — ErrMachineFailed masks it"],"tags":["handshake","state-machine","noise"],"backgroundTag":"handshake-state-invalid","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"}