HMCL-dev/HMCL · error · Exception
Game processor jar does not have main class
Error message
Game processor jar does not have main class ${jar} What it means
Thrown when the processor jar exists but its MANIFEST.MF has no Main-Class attribute (or it is blank). HMCL executes each install processor as `java -cp <jar+classpath> <mainClass>`; without a Main-Class there is no entry point, so the processor configuration is unusable.
Solutions
- Delete the offending jar from the libraries directory and re-run the install so it is re-downloaded
- Verify the jar by opening it (it should be a valid zip with MANIFEST.MF containing Main-Class) and check its size/SHA-1
- Switch to a working download mirror and retry
- Use an official/unmodified NeoForge installer jar; a modified install_profile.json can reference a non-executable jar
Defensive patterns
Strategy: validation
Validate before calling
try (JarFile jf = new JarFile(jar.toFile())) {
String mc = jf.getManifest() == null ? null : jf.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
if (mc == null || mc.isBlank()) reDownload(jar);
} Try / catch
try { task.run(); } catch (Exception e) { if (e.getMessage() != null && e.getMessage().startsWith("Game processor jar does not have main class")) reDownloadCorruptJar(); else throw e; } Prevention
- Verify jar integrity (SHA-1/size) after download
- Use trusted mirrors; an HTML error page saved as a jar lacks a manifest
- Keep installer and libraries from the same version set
When it happens
Trigger: Files.isRegularFile(jar) passed and the JarFile manifest lookup returns null/blank for Attributes.Name.MAIN_CLASS — i.e. a downloaded processor jar that is not an executable jar (corrupted download, wrong artifact, HTML error page saved as jar, or a changed processor spec).
Common situations: Corrupted or truncated download of a Forge/NeoForge processor library; a proxy/mirror serving an error page in place of the jar; manually replaced jar from a wrong version; running an installer whose processor metadata comes from an incompatible (modded/hacked) install_profile.json.
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
- "Missing MANIFEST.MF in file " + modFile
- Bad Implementation-Title
- Bad Build-Number
- client_mappings download info not found
- Game processor file not found, should be downloaded in…
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/61a628adac1d4bd2.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeOldInstallTask.java:122
miss = true;
}
}
if (!processor.getOutputs().isEmpty() && !miss) {
return;
}
Path jar = gameRepository.getLayout().getArtifactFile(processor.getJar());
if (!Files.isRegularFile(jar))
throw new FileNotFoundException("Game processor file not found, should be downloaded in preprocess");
String mainClass;
try (JarFile jarFile = new JarFile(jar.toFile())) {
mainClass = jarFile.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
}
if (StringUtils.isBlank(mainClass))
throw new Exception("Game processor jar does not have main class " + jar);
List<String> command = new ArrayList<>();
command.add(JavaRuntime.getDefault().getBinary().toString());
command.add("-cp");
List<String> classpath = new ArrayList<>(processor.getClasspath().size() + 1);
for (Artifact artifact : processor.getClasspath()) {
Path file = gameRepository.getLayout().getArtifactFile(artifact);
if (!Files.isRegularFile(file))
throw new Exception("Game processor dependency missing");
classpath.add(file.toString());
}
classpath.add(jar.toString());
command.add(String.join(File.pathSeparator, classpath));
command.add(mainClass);
List<String> args = new ArrayList<>(processor.getArgs().size());View on GitHub (pinned to 24702dc5a0)