HMCL-dev/HMCL · error · IOException
No download url is available
Error message
No download url is available
What it means
RemoteVersion.fetch queries HMCL's update metadata endpoint and expects a JSON object containing both "jar" (download URL) and "jarsha1" (hash). If either is missing so a JAR-type RemoteVersion cannot be built, it throws IOException("No download url is available"). This protects against update metadata that lacks a downloadable artifact.
Solutions
- Retry later — the update server metadata may be temporarily incomplete
- Switch to a different update channel in HMCL settings
- Download the latest HMCL jar manually from the official site and replace the current one
- If operating the update server, populate the "jar" and "jarsha1" fields in the channel metadata
Example fix
// before
if (jarUrl != null && jarHash != null) {
return new RemoteVersion(...);
} else {
throw new IOException("No download url is available");
}
// after
if (jarUrl != null && jarHash != null) {
return new RemoteVersion(...);
} else {
throw new IOException("No download url is available for channel " + channel
+ " version " + version + " (jar=" + jarUrl + ")");
} Defensive patterns
Strategy: fallback
Validate before calling
// probe metadata before trusting it
JsonObject meta = JsonParser.parseString(body).getAsJsonObject();
if (!meta.has("jar") || !meta.has("jarsha1")) {
// channel metadata incomplete: fall back to manual download
} Try / catch
try {
RemoteVersion v = RemoteVersion.fetch(channel, version, preview);
} catch (IOException e) {
if (e.getMessage().equals("No download url is available")) {
openOfficialDownloadPage(); // manual update path
} else throw e;
} Prevention
- Retry the update check later; server metadata may be temporarily incomplete
- Keep a manual-update fallback (official website) wired into the UI
- If you run the update server, validate that jar and jarsha1 are always populated
When it happens
Trigger: Checking for updates when the server's metadata JSON has no "jar" or no "jarsha1" entry (null from Optional.orElse(null)) — the channel responds, but without a usable artifact link.
Common situations: Update server misconfiguration; a channel serving metadata-only entries (e.g. announcing updates distributed another way); partial/cached JSON responses; unofficial or deprecated update channels.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Failed to download texture
- Failed to download theme background: HTTP
- Malformed response
- Failed to download dependencies
- Metadata response is empty
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/ed274fd86c9dd162.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/upgrade/RemoteVersion.java:44
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.Optional;
public record RemoteVersion(UpdateChannel channel, String version, String url, Type type, IntegrityCheck integrityCheck,
boolean preview, boolean force) {
public static RemoteVersion fetch(UpdateChannel channel, boolean preview, String url) throws IOException {
try {
JsonObject response = JsonUtils.fromNonNullJson(NetworkUtils.doGet(url), JsonObject.class);
String version = Optional.ofNullable(response.get("version")).map(JsonElement::getAsString).orElseThrow(() -> new IOException("version is missing"));
String jarUrl = Optional.ofNullable(response.get("jar")).map(JsonElement::getAsString).orElse(null);
String jarHash = Optional.ofNullable(response.get("jarsha1")).map(JsonElement::getAsString).orElse(null);
boolean force = Optional.ofNullable(response.get("force")).map(JsonElement::getAsBoolean).orElse(false);
if (jarUrl != null && jarHash != null) {
return new RemoteVersion(channel, version, jarUrl, Type.JAR, new IntegrityCheck("SHA-1", jarHash), preview, force);
} else {
throw new IOException("No download url is available");
}
} catch (JsonParseException e) {
throw new IOException("Malformed response", e);
}
}
@Override
public @NotNull String toString() {
return "[" + version + " from " + url + "]";
}
public enum Type {
JAR
}
}
View on GitHub (pinned to 24702dc5a0)