{"record":{"id":"590e42867ea32832","repo":"slackhq/nebula","slug":"errnocredential","errorCode":"ErrNoCredential","errorMessage":"no handshake credential available for cert version","messagePattern":"no handshake credential available for cert version","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"handshake/errors.go","lineNumber":18,"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":"ErrNoCredential is returned by NewMachine, validateCert, and marshalOutgoing when getCred(version) finds no handshake credential registered for the required certificate version. The node cannot sign or validate certificates for that version without the matching credential. It is wrapped with the requested version number for diagnostics.","triggerScenarios":"NewMachine (machine.go:91) builds a machine for a version whose credential lookup returns nil; validateCert (machine.go:346) hits the same during a handshake when m.myVersion has no registered credential.","commonSituations":"Credential store not yet loaded at handshake time (startup race); peer requests a newer certificate version than this node has keys for; credentials directory misconfigured or empty after redeploy; version bump without distributing new keys.","solutions":["Register/load a credential for the required cert version before starting handshakes (verify getCred returns non-nil)","Check the credentials directory/key files are present and readable in the deployment","Align cert versions between peers, or add support for the peer's version","Gate handshake serving behind credential-load completion to avoid startup races"],"exampleFix":"// before\nm, err := handshake.NewMachine(cs, 2, getCred) // getCcred(nil) for v2\n\n// after\nif getCred(2) == nil {\n    return fmt.Errorf(\"credentials for cert version 2 not loaded\")\n}\nm, err := handshake.NewMachine(cs, 2, getCred)","handlingStrategy":"validation","validationCode":"if getCred(certVersion) == nil {\n    return fmt.Errorf(\"no handshake credential loaded for cert version %d\", certVersion)\n}","typeGuard":"func credentialsReady(versions ...int) bool {\n    for _, v := range versions {\n        if getCred(v) == nil {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":"m, err := handshake.NewMachine(cs, version, getCred)\nif errors.Is(err, handshake.ErrNoCredential) {\n    log.Printf(\"credential for version %v missing; refusing handshake\", version)\n    return\n}","preventionTips":["Load and verify all credential versions at startup before serving handshakes","Keep old-version credentials during rolling upgrades","Health-check that getCred returns non-nil for every advertised version"],"tags":["handshake","credentials","configuration"],"backgroundTag":"missing-credentials","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"}