HMCL-dev/HMCL · error · IOException
Not a valid MultiMC modpack
Error message
Not a valid MultiMC modpack
What it means
Same family as the task-side check but applied while reading the modpack zip: getRootEntryName scans top-level entries to locate the directory containing the instance files (mmc-pack.json etc.) and throws if none qualifies, meaning the archive does not match the MultiMC modpack layout.
Solutions
- Ensure the archive root or a single top-level folder contains mmc-pack.json.
- Select the correct modpack type in the import dialog if the pack is CurseForge/Modrinth format.
- Re-export the instance from MultiMC/Prism Launcher.
Example fix
// before /backup/old/instance/mmc-pack.json -> deeper than one level // after /my-modpack/mmc-pack.json -> detected correctly
Defensive patterns
Strategy: validation
Validate before calling
try (ZipArchiveReader r = new ZipArchiveReader(zip)) {
boolean ok = r.getEntries().stream().anyMatch(e ->
e.getName().equals("mmc-pack.json") || e.getName().matches("[^/]+/mmc-pack.json"));
} Try / catch
try { Modpack m = provider.readManifest(reader, zipPath, encoding); } catch (IOException e) { if (e.getMessage().equals("Not a valid MultiMC modpack")) { /* try another provider */ } } Prevention
- Verify mmc-pack.json is at root or one folder deep before import
- Use the matching provider for CurseForge/Modrinth packs
- Avoid nesting zips inside zips
When it happens
Trigger: MultiMCModpackProvider.getRootEntryName(modpackFile) finds no zip entry whose name ends with the instance file name (mmc-pack.json) at a top-level directory, e.g. during Modpack detection/readManifest.
Common situations: Importing a random zip (not a MultiMC pack) via the MultiMC provider; nested archives (zip inside zip); instance folder more than one level deep.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Not a valid MultiMC modpack
- /assets/
- Cannot load modpacks without Minecraft.
- Curse Forge modpack manifest Mod loader id cannot be blank.
- CurseForge Manifest.gameVersion cannot be blank.
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/8da65ae21f41989b.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackProvider.java:74
return new ModpackUpdateTask(instance, new MultiMCModpackInstallTask(dependencyManager, zipFile, modpack, multiMCInstanceConfiguration, instance));
}
private static String getRootEntryName(ZipArchiveReader file) throws IOException {
final String instanceFileName = "instance.cfg";
if (file.getEntry(instanceFileName) != null) return "";
for (ZipArchiveEntry entry : file.getEntries()) {
String entryName = entry.getName();
int idx = entryName.indexOf('/');
if (idx >= 0
&& entryName.length() == idx + instanceFileName.length() + 1
&& entryName.startsWith(instanceFileName, idx + 1))
return entryName.substring(0, idx + 1);
}
throw new IOException("Not a valid MultiMC modpack");
}
@Override
public Modpack readManifest(ZipArchiveReader modpackFile, Path modpackPath, Charset encoding) throws IOException {
String rootEntryName = getRootEntryName(modpackFile);
MultiMCManifest manifest = MultiMCManifest.readMultiMCModpackManifest(modpackFile, rootEntryName);
String name = rootEntryName.isEmpty() ? FileUtils.getNameWithoutExtension(modpackPath) : rootEntryName.substring(0, rootEntryName.length() - 1);
ZipArchiveEntry instanceEntry = modpackFile.getEntry(rootEntryName + "instance.cfg");
if (instanceEntry == null)
throw new IOException("`instance.cfg` not found, " + modpackFile + " is not a valid MultiMC modpack.");
try (InputStream instanceStream = modpackFile.getInputStream(instanceEntry)) {
MultiMCInstanceConfiguration cfg = new MultiMCInstanceConfiguration(name, instanceStream, manifest);
return new Modpack(cfg.getName(), "", "", cfg.getGameVersion(), cfg.getNotes(), encoding, cfg) {
@Override
public Task<?> getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, GameInstanceID instanceId, String iconUrl) {
return new MultiMCModpackInstallTask(dependencyManager, zipFile, this, cfg, instanceId);View on GitHub (pinned to 24702dc5a0)