HMCL-dev/HMCL · error · IOException

Unknown type of file

Error message

Unknown type of file 

What it means

The NBT editor page determines how to parse a file via NBTFileType.ofFile(file); if no known NBT file type matches, the constructor throws IOException("Unknown type of file " + file). HMCL only supports structured NBT formats (region files, level.dat, player data, etc.), so arbitrary binary or non-NBT files are rejected at page creation.

Solutions

  1. Verify the file is actually an NBT file (level.dat, .mca region, player .dat, etc.)
  2. Update HMCL if the file uses a newer save format
  3. Restore the file from backup if it is corrupted (magic bytes missing)
  4. Use a dedicated NBT tool (e.g. NBTExplorer) or unzip the file if it is a container

Example fix

// before
this.type = NBTFileType.ofFile(file);
if (type == null) {
    throw new IOException("Unknown type of file " + file);
}
// after
// caller-side guard
byte[] head = new byte[4];
try (InputStream in = Files.newInputStream(file)) { in.readNBytes(head, 0, 4); }
if (!NBTFileType.sniffSupported(head))
    Controllers.dialog("Not a supported NBT file: " + file, ...);
Defensive patterns

Strategy: validation

Validate before calling

boolean looksLikeNbt(Path file) throws IOException {
    byte[] head = new byte[2];
    try (InputStream in = Files.newInputStream(file)) {
        if (in.readNBytes(head, 0, 2) != 2) return false;
    }
    return (head[0] & 0xFF) == 0x1F && (head[1] & 0xFF) == 0x8B   // gzip NBT
        || (head[0] & 0xFF) == 0x0A                                 // uncompressed NBT TAG_Compound
        || file.toString().endsWith(".mca") || file.toString().endsWith(".mcr");
}

Try / catch

try {
    openNbtEditor(file);
} catch (IOException e) {
    if (e.getMessage().startsWith("Unknown type of file")) {
        Controllers.dialog("This file is not a supported NBT format");
    } else throw e;
}

Prevention

When it happens

Trigger: Opening a file in HMCL's NBT editor whose signature does not match any registered NBTFileType — e.g. a plain text file, a log file, a zip that is not a recognized NBT container, or corrupted data whose magic bytes were lost.

Common situations: Dragging a random file into the editor; opening a modpack config that is not NBT; edited/corrupted level.dat losing its gzip magic; opening newer save formats an old HMCL version does not recognize.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/ui/nbt/NBTEditorPage.java:70

 * @author Glavo
 */
public final class NBTEditorPage extends SpinnerPane implements DecoratorPage {
    private final ReadOnlyObjectWrapper<State> state;
    private final Path file;
    private final NBTFileType type;

    private final BorderPane root = new BorderPane();

    public NBTEditorPage(Path file) throws IOException {
        getStyleClass().add("gray-background");

        this.state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("nbt.title", file.toString())));
        this.file = file;

        //noinspection DataFlowIssue
        this.type = NBTFileType.ofFile(file);
        if (type == null) {
            throw new IOException("Unknown type of file " + file);
        }

        setContent(root);
        setLoading(true);

        HBox actions = new HBox(8);
        actions.setPadding(new Insets(8));
        actions.setAlignment(Pos.CENTER_RIGHT);

        JFXButton saveButton = FXUtils.newRaisedButton(i18n("button.save"));
        saveButton.setOnAction(e -> {
            try {
                save();
            } catch (IOException ex) {
                LOG.warning("Failed to save NBT file", ex);
                Controllers.dialog(i18n("nbt.save.failed") + "\n\n" + StringUtils.getStackTrace(ex));
            }
        });

View on GitHub (pinned to 24702dc5a0)