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

  1. Read the processor's stdout/stderr in HMCL logs to find the underlying processor failure
  2. Re-download the vanilla Minecraft client JAR and the Forge installer to rule out corrupt inputs
  3. Run with a compatible Java runtime (match the one the Forge version expects)
  4. 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

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


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 the

View on GitHub (pinned to 24702dc5a0)