HMCL-dev/HMCL · error · UnsupportedPlatformException
Candidates
Error message
Candidates: ${candidates} What it means
After locating the per-OS list of Java runtime candidates, MojangJavaDownloadTask scans them for one whose version satisfies the requested major version. If every candidate's parsed version is lower than javaVersion.majorVersion(), it throws UnsupportedPlatformException listing all candidates as JSON, meaning Mojang's index has no runtime new enough for this platform.
Solutions
- Switch to a non-Mojang Java download provider (e.g. Adoptium) which distributes current JDKs.
- Let the game use the highest runtime available by lowering the requested Java major version requirement.
- Refresh the runtime list/clear cache so the latest Mojang index (with newer candidates) is fetched.
- Install the required Java manually and point HMCL at it instead of auto-downloading.
Example fix
// before JavaVersion JAVA_21 = JavaVersion.major(21) with mojang provider; // after (fallback) DownloadProvider p = new AdoptiumDownloadProvider(); // or install Java 21 manually and add it in Java settings
Defensive patterns
Strategy: fallback
Validate before calling
// Check any candidate meets the major version before downloading
boolean any = osDownloads.get(component).stream()
.anyMatch(c -> JavaInfo.parseVersion(c.version().name()) >= javaVersion.majorVersion()); Type guard
if (candidates == null || candidates.isEmpty()) return fallbackProvider();
Try / catch
try { return mojangTask.run().get(); }
catch (UnsupportedPlatformException e) { LOG.warning("No Mojang runtime: " + e.getMessage()); return adoptiumTask.run().get(); } Prevention
- Prefer the newest runtime index (refresh before checking availability).
- Choose Java majors Mojang actually distributes for your OS.
- Always configure a secondary Java provider for majors Mojang lags on.
When it happens
Trigger: Requesting a Java major version (e.g. Java 21) whose component exists for the platform in Mojang's index but whose published runtime versions are all below the requested majorVersion, so the loop over `candidates` completes without a match.
Common situations: Launching a game requiring Java 21 while Mojang's index for your OS only lists older runtimes (index lag after a new MC release); asking for an exact newer major than Mojang distributes; a stale/cached copy of the runtime index.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Unsupported platform
- Failed to download texture
- Incompatible platform: " + javaRuntime.getPlatform()
- Expecting file in terracotta bundle.
- Failed to download theme background: HTTP
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/f9a38de515b76871.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/java/mojang/MojangJavaDownloadTask.java:76
public MojangJavaDownloadTask(DownloadProvider downloadProvider, Path target, Path tempDir, GameJavaVersion javaVersion, String platform) {
this.target = target;
this.tempDir = tempDir;
this.downloadProvider = downloadProvider;
this.javaDownloadsTask = new GetTask(downloadProvider.injectURLWithCandidates(JAVA_LIST_URL))
.thenComposeAsync(javaDownloadsJson -> {
MojangJavaDownloads allDownloads = JsonUtils.fromNonNullJson(javaDownloadsJson, MojangJavaDownloads.class);
Map<String, List<MojangJavaDownloads.JavaDownload>> osDownloads = allDownloads.downloads().get(platform);
if (osDownloads == null || !osDownloads.containsKey(javaVersion.component()))
throw new UnsupportedPlatformException("Unsupported platform: " + platform);
List<MojangJavaDownloads.JavaDownload> candidates = osDownloads.get(javaVersion.component());
for (MojangJavaDownloads.JavaDownload download : candidates) {
if (JavaInfo.parseVersion(download.version().name()) >= javaVersion.majorVersion()) {
this.download = download;
return new GetTask(downloadProvider.injectURLWithCandidates(download.manifest().getUrl()));
}
}
throw new UnsupportedPlatformException("Candidates: " + JsonUtils.GSON.toJson(candidates));
})
.thenApplyAsync(javaDownloadJson -> JsonUtils.fromNonNullJson(javaDownloadJson, MojangJavaRemoteFiles.class));
}
@Override
public Collection<Task<?>> getDependents() {
return Collections.singleton(javaDownloadsTask);
}
@Override
public void execute() throws Exception {
for (Map.Entry<String, MojangJavaRemoteFiles.Remote> entry : javaDownloadsTask.getResult().files().entrySet()) {
Path dest = tempDir.resolve(entry.getKey());
if (entry.getValue() instanceof MojangJavaRemoteFiles.RemoteFile file) {
// Use local file if it already exists
try {
BasicFileAttributes localFileAttributes = Files.readAttributes(dest, BasicFileAttributes.class);
if (localFileAttributes.isRegularFile() && file.getDownloads().containsKey("raw")) {View on GitHub (pinned to 24702dc5a0)