dotnet/aspnetcore · error

Some passkey features are missing. Please update your browse

Error message

Some passkey features are missing. Please update your browser.

What it means

Thrown by obtainCredential when browserSupportsPasskeys is false. The feature gate (PasskeySubmit.razor.js:1-5) requires navigator.credentials, window.PublicKeyCredential, AND the parseCreationOptionsFromJSON / parseRequestOptionsFromJSON methods. Missing any means the browser cannot do modern passkey (conditional mediation, JSON option parsing) flows this component relies on.

Source

Thrown at src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/PasskeySubmit.razor.js:67

        };

        this.internals.form.addEventListener('submit', (event) => {
            if (event.submitter?.name === '__passkeySubmit') {
                event.preventDefault();
                this.obtainAndSubmitCredential();
            }
        });

        this.tryAutofillPasskey();
    }

    disconnectedCallback() {
        this.abortController?.abort();
    }

    async obtainCredential(useConditionalMediation, signal) {
        if (!browserSupportsPasskeys) {
            throw new Error('Some passkey features are missing. Please update your browser.');
        }

        if (this.attrs.operation === 'Create') {
            return await createCredential(signal);
        } else if (this.attrs.operation === 'Request') {
            const email = new FormData(this.internals.form).get(this.attrs.emailName);
            const mediation = useConditionalMediation ? 'conditional' : undefined;
            return await requestCredential(email, mediation, signal);
        } else {
            throw new Error(`Unknown passkey operation '${this.attrs.operation}'.`);
        }
    }

    async obtainAndSubmitCredential(useConditionalMediation = false) {
        this.abortController?.abort();
        this.abortController = new AbortController();
        const signal = this.abortController.signal;
        const formData = new FormData();

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Surface a user-facing message prompting a browser/OS update; offer a password fallback.
  2. Feature-detect before rendering the passkey-submit element and render a fallback UI when unsupported.
  3. Recommend a supported browser (recent Chrome/Edge/Safari/Firefox) with platform authenticator available.
  4. In automation, enable a virtual authenticator.

Example fix

// before
// always render <passkey-submit> regardless of support

// after
const ok = typeof navigator.credentials !== 'undefined' && !!window.PublicKeyCredential?.parseCreationOptionsFromJSON;
if (ok) { /* render passkey-submit */ } else { /* render password form + upgrade notice */ }
Defensive patterns

Strategy: validation

Validate before calling

const passkeysSupported =
  typeof navigator.credentials !== 'undefined' &&
  typeof window.PublicKeyCredential !== 'undefined' &&
  typeof window.PublicKeyCredential.parseCreationOptionsFromJSON === 'function' &&
  typeof window.PublicKeyCredential.parseRequestOptionsFromJSON === 'function';

Type guard

function supportsPasskeys(): boolean {
  return typeof navigator !== 'undefined' && 'credentials' in navigator
    && typeof PublicKeyCredential !== 'undefined'
    && typeof PublicKeyCredential.parseCreationOptionsFromJSON === 'function';
}

Try / catch

null

Prevention

When it happens

Trigger: User on an older or non-Chromium browser (old Safari/Firefox); a browser that supports WebAuthn basics but not the JSON-parse helpers (added later); embedded WebView with restricted APIs; running the component in a headless/automated browser without WebAuthn.

Common situations: Enterprise locked to an older browser; iOS < 16 / macOS < 13; embedded WebViews (older Electron, older Android WebView); CI/automation without virtual authenticator support.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/03bbcae95c62b779. Report an issue: GitHub.