HMCL-dev/HMCL · error · ResponseCodeException

https://api.minecraftservices.com/entitlements/mcstore

Error message

https://api.minecraftservices.com/entitlements/mcstore

What it means

During Microsoft authentication HMCL checks the purchased entitlements via GET https://api.minecraftservices.com/entitlements/mcstore. Any non-200 response is raised as ResponseCodeException with the endpoint URL as its message, aborting authentication because ownership of Java Edition could not be confirmed.

Solutions

  1. Retry authentication later — transient 5xx/outages on minecraftservices.com are common and clear on their own
  2. Check https://xboxstatus.com / Mojang status pages for service incidents
  3. Verify the account actually owns Minecraft: Java Edition or has an active Game Pass for PC subscription
  4. Check network/proxy settings: disable VPN or corporate proxy that could intercept api.minecraftservices.com, then retry

Example fix

// before: single-shot authentication with no retry handling
account.logIn();
// after: tolerate transient entitlement-check failures
try {
    account.logIn();
} catch (ResponseCodeException e) {
    if (String.valueOf(e.getMessage()).contains("entitlements/mcstore")) {
        Thread.sleep(5000); // wait and retry — mcstore is often transiently unavailable
        account.logIn();
    } else {
        throw e;
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check entitlements independently before full login
HttpURLConnection c = HttpRequest.GET("https://api.minecraftservices.com/entitlements/mcstore")
        .authorization("Bearer " + accessToken)
        .createConnection();
if (c.getResponseCode() != 200) { warnUserEntitlementCheckUnavailable(); }

Try / catch

try {
    account.logIn();
} catch (ResponseCodeException e) {
    if (String.valueOf(e.getMessage()).contains("entitlements/mcstore")) {
        Thread.sleep(10_000); // transient mcstore failure — retry with backoff
        account.logIn();
    } else throw e;
}

Prevention

When it happens

Trigger: authenticateViaLiveAccessToken (via authenticate or refresh) gets a status other than 200 from the mcstore entitlements endpoint after 5 retry attempts; token was valid for the login step but rejected here; Mojang service outage; rate limiting or 5xx from minecraftservices.

Common situations: Temporary Mojang/minecraftservices outage or maintenance; account without Java Edition entitlement hitting the endpoint; corporate/firewall proxy intercepting HTTPS and returning an error page; expired access token due to clock skew or long delay between steps.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/87f743a28b621827. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/auth/microsoft/MicrosoftService.java:172

        getUhs(minecraftXstsResponse, uhs);

        // Authenticate with Minecraft
        MinecraftLoginWithXBoxResponse minecraftResponse = HttpRequest
                .POST("https://api.minecraftservices.com/authentication/login_with_xbox")
                .json(mapOf(pair("identityToken", "XBL3.0 x=" + uhs + ";" + minecraftXstsResponse.token)))
                .retry(5)
                .accept("application/json").getJson(MinecraftLoginWithXBoxResponse.class);

        long notAfter = minecraftResponse.expiresIn * 1000L + System.currentTimeMillis();

        // Check MC ownership, this is necessary, see GitHub#2979
        HttpURLConnection request = HttpRequest.GET("https://api.minecraftservices.com/entitlements/mcstore")
                .authorization("Bearer " + minecraftResponse.accessToken)
                .retry(5)
                .accept("application/json").createConnection();

        if (request.getResponseCode() != 200) {
            throw new ResponseCodeException("https://api.minecraftservices.com/entitlements/mcstore", request.getResponseCode());
        }

        // Get Minecraft Account UUID
        MinecraftProfileResponse profileResponse = getMinecraftProfile(minecraftResponse.tokenType, minecraftResponse.accessToken);
        handleErrorResponse(profileResponse);

        return new MicrosoftSession(minecraftResponse.tokenType, minecraftResponse.accessToken, notAfter, liveRefreshToken,
                new MicrosoftSession.User(minecraftResponse.username), new MicrosoftSession.GameProfile(profileResponse.id, profileResponse.name));
    }

    public Optional<MinecraftProfileResponse> getCompleteProfile(String authorization) throws AuthenticationException {
        try {
            return Optional.ofNullable(
                    HttpRequest.GET("https://api.minecraftservices.com/minecraft/profile")
                            .authorization(authorization).getJson(MinecraftProfileResponse.class));
        } catch (IOException e) {
            throw new ServerDisconnectException(e);
        } catch (JsonParseException e) {

View on GitHub (pinned to 24702dc5a0)