microg/GmsCore · error · IllegalStateException

No response set.

Error message

No response set.

What it means

PublicKeyCredential.getResponse() returns whichever of registerResponse, signResponse, or errorResponse was set. If a PublicKeyCredential was constructed with none of them, getResponse() throws IllegalStateException "No response set.", signaling an internally inconsistent credential object.

Source

Thrown at play-services-fido/src/main/java/com/google/android/gms/fido/fido2/api/common/PublicKeyCredential.java:102

    public AuthenticationExtensionsClientOutputs getClientExtensionResults() {
        return clientExtensionResults;
    }

    @Nullable
    public String getId() {
        return id;
    }

    @Nullable
    public byte[] getRawId() {
        return rawId;
    }

    public AuthenticatorResponse getResponse() {
        if (registerResponse != null) return registerResponse;
        if (signResponse != null) return signResponse;
        if (errorResponse != null) return errorResponse;
        throw new IllegalStateException("No response set.");
    }

    @NonNull
    public String getType() {
        return type;
    }

    /**
     * Builder for {@link PublicKeyCredential}.
     */
    public static class Builder {
        @NonNull
        private String id;
        @NonNull
        private byte[] rawId;
        private AuthenticatorResponse response;
        @Nullable
        private AuthenticationExtensionsClientOutputs extensionsClientOutputs;

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Check registerResponse/signResponse/errorResponse (or the source JSON) for null before calling getResponse().
  2. Ensure the PublicKeyCredential is built through the library's Creator/fromJson path with a complete response.
  3. If an error response is expected on failure, make sure the error branch actually sets errorResponse.

Example fix

// before
AuthenticatorResponse resp = credential.getResponse();
// after
if (credential.getRegisterResponse() != null) {
    AuthenticatorAttestationResponse resp = credential.getRegisterResponse();
} else if (credential.getSignResponse() != null) {
    AuthenticatorAssertionResponse resp = credential.getSignResponse();
} else { /* handle missing/error */ }
Defensive patterns

Strategy: validation

Validate before calling

boolean hasResponse = credential.getRegisterResponse() != null || credential.getSignResponse() != null || credential.getErrorResponse() != null;

Type guard

boolean hasResponse(PublicKeyCredential c) { return c.getRegisterResponse() != null || c.getSignResponse() != null || c.getErrorResponse() != null; }

Try / catch

try { response = credential.getResponse(); } catch (IllegalStateException e) { if ("No response set.".equals(e.getMessage())) response = null; else throw e; }

Prevention

When it happens

Trigger: Reading getResponse() on a PublicKeyCredential deserialized/built without any response field populated — e.g. from a Parcel or JSONObject where id/type were present but response was missing or null.

Common situations: Parsing a FIDO server/API response that omitted the response object; a failed parse path where errorResponse wasn't set; constructing PublicKeyCredential manually in tests with only id and type.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/c774514819695c44. Report an issue: GitHub.