HMCL-dev/HMCL · error · IOException
Game processor exited abnormally with code
Error message
Game processor exited abnormally with code
What it means
Thrown when the external Forge game processor JVM process terminates with a nonzero exit code. HMCL runs each processor as 'java -cp ... <mainClass> <args>' and requires a clean exit; any failure inside the processor (bad inputs, corrupt source jar, unsupported Java, OOM) surfaces here wrapped in IOException.
Solutions
- Read the processor's stdout/stderr in HMCL logs to find the underlying processor failure
- Re-download the vanilla Minecraft client JAR and the Forge installer to rule out corrupt inputs
- Run with a compatible Java runtime (match the one the Forge version expects)
- Check free disk space and antivirus logs, then retry the installation
Example fix
// before: default Java may be too old for Forge 1.17+ processors JavaRuntime.getDefault().getBinary() // after: ensure a suitable runtime is selected/configured JavaRuntime runtime = JavaRuntime.fromCurrentJavaVersion(...); // pick Java 8/11/16+ as required command.add(runtime.getBinary().toString());
Defensive patterns
Strategy: try-catch
Try / catch
try {
installTask.run();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Game processor exited abnormally with code")) {
// read processor stderr from HMCL logs; fix inputs (client jar, Java version, disk) and retry
}
} Prevention
- Keep the vanilla client JAR intact and verified before installing Forge
- Match the Java runtime to what the Forge version's processors require
- Ensure adequate free disk space and that antivirus does not block spawned java processes
When it happens
Trigger: SystemUtils.callExternalProcess(command) returns nonzero after executing a Forge processor — e.g. the processor crashed due to a corrupted minecraft jar, wrong Java version, missing native tools, or invalid token substitution in args.
Common situations: Corrupted vanilla client JAR input; running on a Java runtime too old/new for the processor; disk full so the processor cannot write outputs; antivirus blocking the spawned java process.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Processor::jar cannot be null
- Game processor jar does not have main class
- "File " + modFile + " is not a Forge 1.13+ or NeoForge mod."
- "Mod " + modFile + " ` ` is…
- "Missing MANIFEST.MF in file " + modFile
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/348eccd7f8324826.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java:153
classpath.add(jar.toString());
command.add(String.join(File.pathSeparator, classpath));
command.add(mainClass);
List<String> args = new ArrayList<>(processor.getArgs().size());
for (String arg : processor.getArgs()) {
String parsed = parseLiteral(arg, vars);
if (parsed == null)
throw new ArtifactMalformedException("Invalid forge installation configuration");
args.add(parsed);
}
command.addAll(args);
LOG.info("Executing external processor " + processor.getJar().toString() + ", command line: " + new CommandBuilder().addAll(command).toString());
int exitCode = SystemUtils.callExternalProcess(command);
if (exitCode != 0)
throw new IOException("Game processor exited abnormally with code " + exitCode);
for (Map.Entry<String, String> entry : outputs.entrySet()) {
Path artifact = Paths.get(entry.getKey());
if (!Files.isRegularFile(artifact))
throw new FileNotFoundException("File missing: " + artifact);
String code;
try (InputStream stream = Files.newInputStream(artifact)) {
code = DigestUtils.digestToString("SHA-1", stream);
}
if (!Objects.equals(code, entry.getValue())) {
if (!ZlibUtils.IS_ZLIB_COMPATIBLE && FileUtils.getExtension(artifact).equals("jar")) {
// Forge/NeoForge generates JARs dynamically during installation.
// When native compression libraries such as zlib-ng are in use,
// the resulting JAR may be compressed differently, causing its
// SHA-1 hash to differ from the expected value recorded in the
// install profile. In this case, fall back to verifying that theView on GitHub (pinned to 24702dc5a0)