HMCL-dev/HMCL · error · ServerResponseMalformedException
Profile name is missing
Error message
Profile name is missing
What it means
After a successful session refresh, HMCL requires the MicrosoftSession to carry a profile name (the Minecraft username). If acquiredSession.hasProfileName() is false, ServerResponseMalformedException('Profile name is missing') is thrown since a session without a username cannot produce valid AuthInfo.
Solutions
- Launch Minecraft once with the official launcher (or create the profile at minecraft.net) so the account has a username, then retry login
- Check that the account actually owns Java Edition / has an active Game Pass subscription
- Retry later if Mojang/microsoftservices is having an outage returning partial profile data
- Re-add the account in HMCL to force a full fresh login rather than refresh
Example fix
// before: assuming any authenticated account has a profile
account.logIn();
// after: check entitlements/profile existence first
if (!account.getService().getProfileType().equals(AccountProfileType.MOJANG)
|| !hasMinecraftProfile(account)) {
throw new UnsupportedOperationException("This Microsoft account has no Minecraft profile; buy the game or create the profile first.");
}
account.logIn(); Defensive patterns
Strategy: try-catch
Validate before calling
// check profile/entitlement existence before login // GET https://api.minecraftservices.com/minecraft/profile with a fresh token; a 404 means no profile name exists yet
Try / catch
try {
account.logIn();
} catch (ServerResponseMalformedException e) {
if ("Profile name is missing".equals(e.getMessage())) {
// account has no Minecraft profile; instruct user to create it
} else throw e;
} Prevention
- Ensure the account owns Java Edition and has launched the game at least once
- Check for Mojang outages before bulk logins
- Re-authenticate fully rather than relying on refresh for accounts in unusual states
When it happens
Trigger: The Microsoft/minecraftservices profile endpoint returns a session with an id but no name — typically because the account does not own the game or has no Minecraft profile yet, while the refresh path still produced a session object.
Common situations: Account owns Minecraft: Java Edition but the profile was never created (never launched the game); Xbox Game Pass entitlement not yet provisioned; account is a demo/unmigrated state; the microsoftservices profile API returned partial data during an outage.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Selected profile changed
- uhs mismatched
- https://api.minecraftservices.com/minecraft/profile
- https://api.minecraftservices.com/entitlements/mcstore
- Failed to upload skin, response code:
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/9b4f5ff993903eb2.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/auth/microsoft/MicrosoftAccount.java:89
@Override
public UUID getProfileID() {
return session.profile().id();
}
@Override
public AuthInfo logIn() throws AuthenticationException {
if (!authenticated || !session.hasProfileName() || System.currentTimeMillis() > session.notAfter()) {
if (session.hasProfileName()
&& service.validate(session.notAfter(), session.tokenType(), session.accessToken())) {
authenticated = true;
} else {
MicrosoftSession acquiredSession = service.refresh(session);
if (!Objects.equals(acquiredSession.profile().id(), session.profile().id())) {
throw new ServerResponseMalformedException("Selected profile changed");
}
if (!acquiredSession.hasProfileName()) {
throw new ServerResponseMalformedException("Profile name is missing");
}
session = acquiredSession;
authenticated = true;
invalidate();
}
}
return session.toAuthInfo();
}
@Override
public AuthInfo logInWhenCredentialsExpired() throws AuthenticationException {
MicrosoftSession acquiredSession = service.authenticate(OAuth.GrantFlow.DEVICE);
if (!Objects.equals(profileID, acquiredSession.profile().id())) {
throw new WrongAccountException(profileID, acquiredSession.profile().id());
}View on GitHub (pinned to 24702dc5a0)