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
- Retry authentication later — transient 5xx/outages on minecraftservices.com are common and clear on their own
- Check https://xboxstatus.com / Mojang status pages for service incidents
- Verify the account actually owns Minecraft: Java Edition or has an active Game Pass for PC subscription
- 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
- Check Mojang/Xbox status pages during incidents
- Disable VPN/proxies that may intercept api.minecraftservices.com
- Confirm the account owns Java Edition before login
- Use exponential backoff for automated retries
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
- https://api.minecraftservices.com/minecraft/profile
- Failed to download theme background: HTTP
- Failed to upload skin, response code:
- Unexpected file size
- Too much redirects
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)