{"record":{"id":"b5bfe785a02cc509","repo":"HMCL-dev/HMCL","slug":"https-api-minecraftservices-com-minecraft-profil","errorCode":null,"errorMessage":"https://api.minecraftservices.com/minecraft/profile","messagePattern":"https://api\\.minecraftservices\\.com/minecraft/profile","errorType":"http","errorClass":"ResponseCodeException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/auth/microsoft/MicrosoftService.java","lineNumber":264,"sourceCode":"    private static MinecraftProfileResponse getMinecraftProfile(String tokenType, String accessToken)\n            throws IOException, AuthenticationException {\n        HttpURLConnection conn = HttpRequest.GET(\"https://api.minecraftservices.com/minecraft/profile\")\n                .authorization(tokenType, accessToken)\n                .createConnection();\n        int responseCode = conn.getResponseCode();\n        if (responseCode == HTTP_NOT_FOUND) {\n            MinecraftLicense license = HttpRequest.GET(\"https://api.minecraftservices.com/entitlements/license\")\n                    .authorization(tokenType, accessToken)\n                    .getJson(MinecraftLicense.class);\n            boolean hasMinecraftLicense = license != null && license.items() != null && license.items().stream()\n                    .anyMatch(item -> \"game_minecraft\".equals(item.name()));\n            if (!hasMinecraftLicense) {\n                throw new MinecraftJavaEditionLicenseNotFoundException();\n            } else {\n                throw new MinecraftJavaEditionProfileNotFoundException();\n            }\n        } else if (responseCode != 200) {\n            throw new ResponseCodeException(\"https://api.minecraftservices.com/minecraft/profile\", responseCode);\n        }\n\n        String result = NetworkUtils.readFullyAsString(conn);\n        return JsonUtils.fromNonNullJson(result, MinecraftProfileResponse.class);\n    }\n\n    public Optional<CompleteGameProfile> getCompleteGameProfile(UUID uuid) throws AuthenticationException {\n        Objects.requireNonNull(uuid);\n\n        return Optional.ofNullable(GSON.fromJson(request(\"https://sessionserver.mojang.com/session/minecraft/profile/\" + UUIDs.toCompactString(uuid), null), CompleteGameProfile.class));\n    }\n\n    public void uploadSkin(String accessToken, boolean isSlim, Path file) throws AuthenticationException, UnsupportedOperationException {\n        try {\n            HttpURLConnection con = NetworkUtils.createHttpConnection(\"https://api.minecraftservices.com/minecraft/profile/skins\");\n            con.setRequestMethod(\"POST\");\n            con.setRequestProperty(\"Authorization\", \"Bearer \" + accessToken);\n            con.setDoOutput(true);","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/microsoft/MicrosoftService.java#L246-L282","documentation":"getMinecraftProfile requests GET https://api.minecraftservices.com/minecraft/profile to fetch the player's profile. If the response code is neither 204 (handled specially, raising license/profile-not-found exceptions) nor 200, ResponseCodeException with the endpoint URL is thrown, meaning an unexpected HTTP status blocked profile retrieval.","triggerScenarios":"Called from profileResponse and validate; the endpoint returns 401 (access token expired or invalid), 403, 429 (rate limited), or 5xx — anything unexpected — so validate() or profile fetching fails with this exception.","commonSituations":"Mojang rate limiting after many logins (429); token expiry between login steps; temporary microsoftservices outage (5xx); overly frequent validate calls; network middleboxes altering the response.","solutions":["Wait and retry — 429/5xx are usually transient; space out repeated logins/validations","Re-authenticate the account so a fresh access token is used (401 usually means token expired)","Check Mojang/Xbox service status for ongoing incidents","Check local network/proxy configuration that might tamper with HTTPS responses"],"exampleFix":"// before: validating aggressively in a loop\nwhile (!account.getService().validate(...)) { }\n// after: back off and refresh on unexpected statuses\nif (!account.getService().validate(notAfter, tokenType, accessToken)) {\n    Thread.sleep(30_000); // avoid 429 rate limit on /minecraft/profile\n    account.logIn(); // get a fresh access token\n}","handlingStrategy":"retry","validationCode":"// pre-flight the profile endpoint before heavy operations\nHttpURLConnection c = HttpRequest.GET(\"https://api.minecraftservices.com/minecraft/profile\")\n        .authorization(\"Bearer \" + accessToken).createConnection();\nint code = c.getResponseCode();\nif (code == 429) Thread.sleep(60_000); // rate limited\nelse if (code == 401) refreshTokenFirst();","typeGuard":null,"tryCatchPattern":"try {\n    account.validate(notAfter, tokenType, accessToken);\n} catch (ResponseCodeException e) {\n    if (String.valueOf(e.getMessage()).contains(\"/minecraft/profile\")) {\n        Thread.sleep(30_000); // back off, then refresh credentials and retry\n        account.logIn();\n    } else throw e;\n}","preventionTips":["Throttle frequent validate/login calls to avoid 429","Refresh tokens before they expire to prevent 401s","Monitor Mojang status for 5xx windows","Avoid proxies that tamper with HTTPS responses"],"tags":["http","network","microsoft","profile"],"backgroundTag":"http-error-response","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}