{"record":{"id":"51335dc1afda5022","repo":"NationalSecurityAgency/ghidra","slug":"missing-ghidra-project-archive-gar-marker-file","errorCode":null,"errorMessage":"Missing Ghidra Project Archive (.gar) marker file","messagePattern":"Missing Ghidra Project Archive \\(\\.gar\\) marker file","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/archive/RestoreTask.java","lineNumber":122,"sourceCode":"\t\t\t\t\t\" to \\n \" + projectDir + eMsg,\n\t\t\t\te);\n\t\t\tMsg.info(this, \"Restore Archive: \" + locInfo + \" failed.\");\n\t\t}\n\t}\n\n\tprivate void createProjectMarkerFile() throws IOException {\n\t\tif (!projectFile.createNewFile()) {\n\t\t\tthrow new IOException(\"Couldn't create file \" + projectFile.getAbsolutePath());\n\t\t}\n\t}\n\n\tprivate void verifyArchive(GFileSystem fs, TaskMonitor monitor) throws IOException {\n\t\tif (!fs.getFSRL().getProtocol().equals(\"zip\")) {\n\t\t\tthrow new IOException(\"Not a zip file: \" + fs.getFSRL());\n\t\t}\n\t\tGFile magicFile = fs.lookup(\"/\" + ArchivePlugin.JAR_VERSION_TAG);\n\t\tif (magicFile == null) {\n\t\t\tthrow new IOException(\"Missing Ghidra Project Archive (.gar) marker file\");\n\t\t}\n\t}\n\n\t@Override\n\tprotected void processFile(GFile file, File destFSFile, TaskMonitor monitor)\n\t\t\tthrows IOException, CancelledException {\n\t\tif (!shouldSkip(file)) {\n\t\t\tsuper.processFile(file, destFSFile, monitor);\n\t\t}\n\t}\n\n\t@Override\n\tprotected void processDirectory(GFile srcGFileDirectory, File destDirectory,\n\t\t\tTaskMonitor monitor) throws IOException, CancelledException {\n\t\tif (!shouldSkip(srcGFileDirectory)) {\n\t\t\tsuper.processDirectory(srcGFileDirectory, destDirectory, monitor);\n\t\t}\n\t}","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/archive/RestoreTask.java#L104-L140","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nGFile magicFile = fs.lookup(\"/\" + ArchivePlugin.JAR_VERSION_TAG);\nif (magicFile == null) {\n    throw new IOException(\"Missing Ghidra Project Archive (.gar) marker file\");\n}\n\n// after — list root entries for a more actionable error\nGFile magicFile = fs.lookup(\"/\" + ArchivePlugin.JAR_VERSION_TAG);\nif (magicFile == null) {\n    List<String> roots = fs.getListing(null).stream().map(GFile::getName).collect(Collectors.toList());\n    throw new IOException(\"Missing Ghidra Project Archive marker '\" + ArchivePlugin.JAR_VERSION_TAG +\n        \"'. Root entries present: \" + roots);\n}","handlingStrategy":"validation","validationCode":"GFile magic = fs.lookup(\"/\" + ArchivePlugin.JAR_VERSION_TAG);\nif (magic == null) {\n    // not a recognized Ghidra archive — do not proceed\n    throw new IOException(\"Missing Ghidra Project Archive marker '\" + ArchivePlugin.JAR_VERSION_TAG + \"'\");\n}","typeGuard":"boolean isGhidraArchive = fs.lookup(\"/\" + ArchivePlugin.JAR_VERSION_TAG) != null;","tryCatchPattern":"try {\n    verifyArchive(fs, monitor);\n} catch (IOException e) {\n    Msg.showError(this, null, \"Restore Failed\", \"File is not a recognized Ghidra archive: \" + e.getMessage());\n}","preventionTips":["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."],"tags":["ghidra","archive","restore","zip","io","validation"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}