HMCL-dev/HMCL · error · IOException
Fabric metadata is invalid
Error message
Fabric metadata is invalid
What it means
Thrown by FabricInstallTask.execute when Gson parses the Fabric launcher metadata but yields null, meaning the downloaded JSON is empty, malformed, or not deserializable into FabricInfo. The install cannot proceed without valid loader metadata.
Solutions
- Check network connectivity / retry the download of Fabric metadata
- Verify the Fabric meta URL and requested loader/game version are valid
- Inspect the raw getResult() payload to see what was actually downloaded
Example fix
// before
FabricInfo fabricInfo = JsonUtils.GSON.fromJson(launchMetaTask.getResult(), FabricInfo.class);
if (fabricInfo == null) throw new IOException("Fabric metadata is invalid");
// after
String raw = launchMetaTask.getResult();
if (raw == null || raw.isBlank() || !raw.trim().startsWith("{"))
throw new IOException("Fabric metadata download failed, got: " + preview(raw)); Defensive patterns
Strategy: try-catch
Validate before calling
String raw = launchMetaTask.getResult();
if (raw == null || raw.isBlank() || !raw.stripLeading().startsWith("{"))
throw new IOException("Fabric metadata is not valid JSON: " + (raw == null ? "null" : raw.substring(0, Math.min(120, raw.length())))); Type guard
static boolean looksLikeJson(String s) {
return s != null && !s.isBlank() && (s.stripLeading().startsWith("{") || s.stripLeading().startsWith("["));
} Try / catch
try {
installTask.execute();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("Fabric metadata")) {
ui.showError("Could not read Fabric metadata; check network/mirror and retry");
}
} Prevention
- Verify connectivity to fabricmc.net meta endpoints before install
- Pin supported Fabric loader/game versions
- Log the raw payload on failure to distinguish outage vs schema change
When it happens
Trigger: launchMetaTask.getResult() returns an empty string, invalid JSON, or JSON whose shape Gson cannot map to FabricInfo (GSON.fromJson returns null on empty input).
Common situations: Fabric meta API outage or HTML error page returned instead of JSON, wrong metadata URL, proxy/captive portal interference, or unsupported Fabric version endpoint.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- Failed to download texture
- Missing game manifest
- Game manifest inherits from another manifest
- Unsupported checksum type:
- Missing download URI:
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/d9523c6f0642ca6f.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/fabric/FabricInstallTask.java:92
public Collection<Task<?>> getDependents() {
return Collections.singleton(launchMetaTask);
}
@Override
public Collection<Task<?>> getDependencies() {
return dependencies;
}
@Override
public boolean isRelyingOnDependencies() {
return false;
}
@Override
public void execute() throws IOException {
FabricInfo fabricInfo = JsonUtils.GSON.fromJson(launchMetaTask.getResult(), FabricInfo.class);
if (fabricInfo == null)
throw new IOException("Fabric metadata is invalid");
setResult(getPatch(fabricInfo, remote.getGameVersion(), remote.getSelfVersion()));
dependencies.add(new GameLibrariesTask(dependencyManager, manifest, true, getResult().getLibraries()));
}
private GameInstancePatch getPatch(FabricInfo fabricInfo, String gameVersion, String loaderVersion) {
JsonObject launcherMeta = fabricInfo.launcherMeta;
Arguments arguments = new Arguments();
String mainClass;
if (!launcherMeta.get("mainClass").isJsonObject()) {
mainClass = launcherMeta.get("mainClass").getAsString();
} else {
mainClass = launcherMeta.get("mainClass").getAsJsonObject().get("client").getAsString();
}
if (launcherMeta.has("launchwrapper")) {View on GitHub (pinned to 24702dc5a0)