NationalSecurityAgency/ghidra · error · IOException
Missing Ghidra Project Archive (.gar) marker file
Error message
Missing Ghidra Project Archive (.gar) marker file
What it means
Thrown as IOException by RestoreTask.verifyArchive when the zip filesystem does not contain the JAR_VERSION_TAG marker file at its root. Ghidra writes this marker into every project archive to identify it as a valid Ghidra archive; its absence means the zip is valid but not a Ghidra project archive.
Source
Thrown at Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/archive/RestoreTask.java:122
" to \n " + projectDir + eMsg,
e);
Msg.info(this, "Restore Archive: " + locInfo + " failed.");
}
}
private void createProjectMarkerFile() throws IOException {
if (!projectFile.createNewFile()) {
throw new IOException("Couldn't create file " + projectFile.getAbsolutePath());
}
}
private void verifyArchive(GFileSystem fs, TaskMonitor monitor) throws IOException {
if (!fs.getFSRL().getProtocol().equals("zip")) {
throw new IOException("Not a zip file: " + fs.getFSRL());
}
GFile magicFile = fs.lookup("/" + ArchivePlugin.JAR_VERSION_TAG);
if (magicFile == null) {
throw new IOException("Missing Ghidra Project Archive (.gar) marker file");
}
}
@Override
protected void processFile(GFile file, File destFSFile, TaskMonitor monitor)
throws IOException, CancelledException {
if (!shouldSkip(file)) {
super.processFile(file, destFSFile, monitor);
}
}
@Override
protected void processDirectory(GFile srcGFileDirectory, File destDirectory,
TaskMonitor monitor) throws IOException, CancelledException {
if (!shouldSkip(srcGFileDirectory)) {
super.processDirectory(srcGFileDirectory, destDirectory, monitor);
}
}View on GitHub (pinned to d5f144c24d)
Solutions
- Use a Ghidra project archive (.gar) created by ArchivePlugin; verify it contains the version-tag file at its root.
- Re-create the archive from a valid open Ghidra project.
- If migrating across Ghidra versions, export a fresh archive from the version that owns the project.
- Catch IOException and inform the user the file is not a recognized Ghidra archive.
Example fix
// before
GFile magicFile = fs.lookup("/" + ArchivePlugin.JAR_VERSION_TAG);
if (magicFile == null) {
throw new IOException("Missing Ghidra Project Archive (.gar) marker file");
}
// after — list root entries for a more actionable error
GFile magicFile = fs.lookup("/" + ArchivePlugin.JAR_VERSION_TAG);
if (magicFile == null) {
List<String> roots = fs.getListing(null).stream().map(GFile::getName).collect(Collectors.toList());
throw new IOException("Missing Ghidra Project Archive marker '" + ArchivePlugin.JAR_VERSION_TAG +
"'. Root entries present: " + roots);
} Defensive patterns
Strategy: validation
Validate before calling
GFile magic = fs.lookup("/" + ArchivePlugin.JAR_VERSION_TAG);
if (magic == null) {
// not a recognized Ghidra archive — do not proceed
throw new IOException("Missing Ghidra Project Archive marker '" + ArchivePlugin.JAR_VERSION_TAG + "'");
} Type guard
boolean isGhidraArchive = fs.lookup("/" + ArchivePlugin.JAR_VERSION_TAG) != null; Try / catch
try {
verifyArchive(fs, monitor);
} catch (IOException e) {
Msg.showError(this, null, "Restore Failed", "File is not a recognized Ghidra archive: " + e.getMessage());
} Prevention
- Use only .gar archives created by ArchivePlugin.
- Re-export a fresh archive when migrating across versions.
- List root entries in the error to help users diagnose a wrong file.
When it happens
Trigger: verifyArchive confirms the protocol is zip, then fs.lookup("/" + ArchivePlugin.JAR_VERSION_TAG) returns null — the archive is a zip but lacks the Ghidra marker, e.g. an arbitrary zip file, an archive from an incompatible/older Ghidra version, or a truncated archive.
Common situations: User picks a random .zip/.jar instead of a .gar; archive was partially extracted/corrupted losing the root marker; cross-version archive where the tag name changed; an archive produced by a tool other than Ghidra.
Related errors
- Not a zip file: " + fs.getFSRL()
- Couldn't create file " + projectFile.getAbsolutePath()
- Bad filename in archive: \"" + filename + "\"
- Unsupported value: {}
- Invalid value for {}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/51335dc1afda5022.
Report an issue: GitHub.