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
- Verify the file is actually an NBT file (level.dat, .mca region, player .dat, etc.)
- Update HMCL if the file uses a newer save format
- Restore the file from backup if it is corrupted (magic bytes missing)
- 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
- Only open known NBT files (level.dat, .dat player data, .mca region files)
- Update HMCL when Minecraft introduces new save formats
- Check gzip/NBT magic bytes (1F 8B or 0x0A) before opening
- Keep backups of save files before editing
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
- level.dat missing LevelName
- level.dat missing LastPlayed
- "File " + file + " is not a valid mod file."
- "File '" + file + "' is not a resource pack"
- accountID is missing
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)