gravitational/teleport · error

authclient.ErrNoMFADevices.Error()

Error message

authclient.ErrNoMFADevices.Error()

What it means

In the app connections handler's ServeHTTP error path, when the error is authclient.ErrNoMFADevices the response body is that sentinel's message ('no MFA devices found'), telling the user their per-session-MFA-gated app request failed because they have no MFA devices registered.

Source

Thrown at lib/srv/app/connections_handler.go:899

		c.log.ErrorContext(c.closeContext, "Unable to extract connection from context.")
	}
	err := c.getAndDeleteConnAuth(conn)
	if err == nil {
		err = c.serveHTTP(w, r)
	}
	if err != nil {
		c.log.WarnContext(c.closeContext, "Failed to serve request", "error", err)

		// Convert trace error type to HTTP and write response, make sure we close the
		// connection afterwards so that the monitor is recreated if needed.
		code := trace.ErrorToCode(err)
		w.Header().Set("Connection", "close")

		switch {
		case errors.Is(err, services.ErrTrustedDeviceRequired):
			writeTrustedDeviceRequired(w, r, code)
		case errors.Is(err, services.ErrSessionMFARequired):
			http.Error(w, authclient.ErrNoMFADevices.Error(), code)
		default:
			http.Error(w, http.StatusText(code), code)
		}
	}
}

const (
	trustedDeviceRequiredDocsURL          = "https://goteleport.com/docs/zero-trust-access/device-trust/device-management/#troubleshooting"
	trustedDeviceRequiredWebUIDocsURL     = "https://goteleport.com/docs/zero-trust-access/device-trust/device-management/#web-ui-fails-to-authenticate-trusted-device"
	trustedDeviceRequiredAppAccessDocsURL = "https://goteleport.com/docs/zero-trust-access/device-trust/device-management/#app-access-and-access-to-this-app-requires-a-trusted-device"
)

// writeTrustedDeviceRequired writes the response body for a request that failed
// with [services.ErrTrustedDeviceRequired]. Browsers receive a small HTML page
// with clickable links to the docs; every other client gets plain text.
func writeTrustedDeviceRequired(w http.ResponseWriter, r *http.Request, code int) {
	if isBrowserUserAgent(r.UserAgent()) {
		const body = `<!DOCTYPE html>

View on GitHub (pinned to 1283425b60)

Solutions

  1. Register an MFA device: tsh mfa add
  2. Use a cluster/auth preference that does not require per-session MFA for this app, if appropriate
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at lib/srv/app/connections_handler.go:899 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/7070b376e3def9e6. Report an issue: GitHub.