{"record":{"id":"ebb639f756fad033","repo":"gravitational/teleport","slug":"user-has-only-invalid-webauthn-registrations-cons","errorCode":null,"errorMessage":"user has only invalid WebAuthn registrations, consider a user reset","messagePattern":"user has only invalid WebAuthn registrations, consider a user reset","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/auth/webauthn/login_mfa.go","lineNumber":38,"sourceCode":"\nimport (\n\t\"context\"\n\t\"errors\"\n\n\t\"github.com/gravitational/trace\"\n\n\tmfav1 \"github.com/gravitational/teleport/api/gen/proto/go/teleport/mfa/v1\"\n\tmfav2 \"github.com/gravitational/teleport/api/gen/proto/go/teleport/mfa/v2\"\n\t\"github.com/gravitational/teleport/api/types\"\n\twantypes \"github.com/gravitational/teleport/lib/auth/webauthntypes\"\n)\n\n// ErrInvalidCredentials is a special kind of credential \"NotFound\" error, where\n// the user has only devices registered to other RPIDs.\n// Possible fixes include reseting the affected users (likely the entire\n// cluster), or rolling back to a good WebAuthn configuration (if still\n// possible).\nvar ErrInvalidCredentials = errors.New(\"user has only invalid WebAuthn registrations, consider a user reset\")\n\n// LoginIdentity represents the subset of Identity methods used by LoginFlow.\n// It exists to better scope LoginFlow's use of Identity and to facilitate\n// testing.\ntype LoginIdentity interface {\n\tGetWebauthnLocalAuth(ctx context.Context, user string) (*types.WebauthnLocalAuth, error)\n\n\tGetMFADevices(ctx context.Context, user string, withSecrets bool) ([]*types.MFADevice, error)\n\tUpsertMFADevice(ctx context.Context, user string, d *types.MFADevice) error\n\tUpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error\n\tGetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error)\n\tDeleteWebauthnSessionData(ctx context.Context, user, sessionID string) error\n}\n\n// WithDevices returns a LoginIdentity backed by a fixed set of devices.\n// The supplied devices are returned in all GetMFADevices calls.\nfunc WithDevices(identity LoginIdentity, devs []*types.MFADevice) LoginIdentity {\n\treturn &loginWithDevices{","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/lib/auth/webauthn/login_mfa.go#L20-L56","documentation":"ErrInvalidCredentials signals a special NotFound case: the user exists but every WebAuthn device on record is registered to a different RelyingParty ID (RPID), so none of them can satisfy the current login. It is returned by begin/LoginFlow and surfaced through IsCredentialsError/VerifyCredentials. The fix is administrative, not user-side: reset the affected users or restore a working WebAuthn configuration.","triggerScenarios":"Login at webauthn/login.go:157 when all of a user's credentials fail RPID validation (foundInvalid=true, len(u.credentials)==0), typically during webauthn.Begin / LoginFlow MFA or passwordless login.","commonSituations":"Cluster's WebAuthn RPID (auth_server config) changed after devices were registered (e.g. moving from hostname to cluster name); rollback to older teleport after RPID migration; restoring a cluster under a different public address.","solutions":["Restore the original WebAuthn configuration (the same RPID as when devices were registered) if a rollback is still possible.","Reset the affected users' MFA devices: tctl mfa reset or have users re-register via tsh mfa add after admin reset.","If the whole cluster is affected, plan a coordinated user reset across the cluster.","Before changing RPID, follow Teleport docs on WebAuthn RPID migration to avoid orphaned registrations."],"exampleFix":"# before (auth_server config with new RPID while users are registered to old one)\n# after: restore previous RPID or reset users\n$ tctl mfa reset --user=alice","handlingStrategy":"type-guard","validationCode":"// server-side: compare cluster RPID to the RPID embedded in users' registered credentials before login","typeGuard":"if wanlib.IsCredentialsError(err) {\n\t// treat as RPID-invalid case; prompt admin reset instead of re-registration\n}","tryCatchPattern":"resp, err := flow.Login(ctx, req)\nif wanlib.IsCredentialsError(err) {\n\treturn trace.BadParameter(\"your MFA devices are registered to a different RPID; contact an admin to reset MFA\")\n}","preventionTips":["Never change the cluster WebAuthn RPID without a migration plan.","Snapshot WebAuthn config before upgrades/rollbacks so the old RPID can be restored.","Communicate planned user resets; use tctl mfa reset for affected users.","Follow Teleport RFD/docs on RPID changes before moving cluster addresses."],"tags":["webauthn","rpid","mfa","user-reset"],"backgroundTag":"webauthn-rpid-mismatch","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}