HMCL-dev/HMCL · error · IOException

Unrecognized OptiFine installer

Error message

Unrecognized OptiFine installer

What it means

Thrown when the Config.class found in the OptiFine installer lacks required string constants MC_VERSION, OF_EDITION, or OF_RELEASE. HMCL cannot determine which game version the installer targets, so it refuses to proceed.

Solutions

  1. Download the installer from the official OptiFine site to get an unmodified build.
  2. Verify the jar's Config.class contains MC_VERSION/OF_EDITION/OF_RELEASE constants (javap -constants).
  3. Use an older, known-good OptiFine build for the target game version.

Example fix

// before
if (mcVersion == null || ofEdition == null || ofRelease == null)
    throw new IOException("Unrecognized OptiFine installer");
// after
if (mcVersion == null || ofEdition == null || ofRelease == null)
    throw new IOException("Unrecognized OptiFine installer: missing "
        + (mcVersion == null ? "MC_VERSION " : "") + (ofEdition == null ? "OF_EDITION " : "")
        + (ofRelease == null ? "OF_RELEASE" : "") + " in Config.class");
Defensive patterns

Strategy: validation

Validate before calling

String constants = new String(Files.readAllBytes(configClass), StandardCharsets.ISO_8859_1);
if (!constants.contains("MC_VERSION") || !constants.contains("OF_EDITION"))
    throw new IllegalArgumentException("Not a standard OptiFine installer");

Try / catch

try {
    await(task);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("Unrecognized OptiFine installer")) {
        // re-download unmodified installer from official site
    }
}

Prevention

When it happens

Trigger: Parsing the constant pool of Config.class via ConstantPoolScanner and finding any of mcVersion/ofEdition/ofRelease null — i.e. the jar looks like an OptiFine installer structurally but its metadata constants are missing or the class format is too new to parse.

Common situations: Tampered/refactored OptiFine builds, obfuscated or repackaged jars from mirrors, or future OptiFine versions that change constant names.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/b0ef0401a5a87927. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/optifine/OptiFineInstallTask.java:280

    public static Task<GameInstancePatch> install(
            DefaultDependencyManager dependencyManager,
            GameInstanceManifest manifest,
            String gameVersion,
            Path installer) throws IOException, VersionMismatchException {
        try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
            Path configClass = fs.getPath("Config.class");
            if (!Files.exists(configClass)) configClass = fs.getPath("net/optifine/Config.class");
            if (!Files.exists(configClass)) configClass = fs.getPath("notch/net/optifine/Config.class");
            if (!Files.exists(configClass)) throw new IOException("Unrecognized installer");
            ConstantPool pool = ConstantPoolScanner.parse(Files.readAllBytes(configClass), ConstantType.UTF8);
            List<String> constants = new ArrayList<>();
            pool.list(Utf8Constant.class).forEach(utf8 -> constants.add(utf8.get()));
            String mcVersion = getOrDefault(constants, constants.indexOf("MC_VERSION") + 1, null);
            String ofEdition = getOrDefault(constants, constants.indexOf("OF_EDITION") + 1, null);
            String ofRelease = getOrDefault(constants, constants.indexOf("OF_RELEASE") + 1, null);

            if (mcVersion == null || ofEdition == null || ofRelease == null)
                throw new IOException("Unrecognized OptiFine installer");

            if (!mcVersion.equals(gameVersion))
                throw new VersionMismatchException(mcVersion, gameVersion);

            OptiFineRemoteVersion remoteVersion = new OptiFineRemoteVersion(
                    mcVersion,
                    ofEdition + "_" + ofRelease,
                    Collections.singletonList(""),
                    false);
            return new GameDownloadTask(dependencyManager, manifest)
                    .thenComposeAsync(minecraftJar -> new OptiFineInstallTask(
                            dependencyManager,
                            manifest,
                            remoteVersion,
                            minecraftJar,
                            installer));
        }
    }

View on GitHub (pinned to 24702dc5a0)