{"record":{"id":"3215c749ad9fe74c","repo":"jenkinsci/jenkins","slug":"failed-to-expand","errorCode":null,"errorMessage":"Failed to expand {}","messagePattern":"Failed to expand (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/hudson/ClassicPluginStrategy.java","lineNumber":484,"sourceCode":"     * Explodes the plugin into a directory, if necessary.\n     */\n    private static void explode(File archive, File destDir) throws IOException {\n        Util.createDirectories(Util.fileToPath(destDir));\n\n        // timestamp check\n        File explodeTime = new File(destDir, \".timestamp2\");\n        if (explodeTime.exists() && explodeTime.lastModified() == archive.lastModified())\n            return; // no need to expand\n\n        // delete the contents so that old files won't interfere with new files\n        Util.deleteRecursive(destDir);\n\n        try {\n            Project prj = new Project();\n            unzipExceptClasses(archive, destDir, prj);\n            createClassJarFromWebInfClasses(archive, destDir, prj);\n        } catch (BuildException x) {\n            throw new IOException(\"Failed to expand \" + archive, x);\n        }\n\n        try {\n            new FilePath(explodeTime).touch(archive.lastModified());\n        } catch (InterruptedException e) {\n            throw new AssertionError(e); // impossible\n        }\n    }\n\n    /**\n     * Repackage classes directory into a jar file to make it remoting friendly.\n     * The remoting layer can cache jar files but not class files.\n     */\n    private static void createClassJarFromWebInfClasses(File archive, File destDir, Project prj) throws IOException {\n        File classesJar = new File(destDir, \"WEB-INF/lib/classes.jar\");\n\n        ZipFileSet zfs = new ZipFileSet();\n        zfs.setProject(prj);","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/core/src/main/java/hudson/ClassicPluginStrategy.java#L466-L502","documentation":"Thrown by explode() when Ant's unzip task raises BuildException while extracting a plugin archive into its exploded directory. Jenkins deletes the old exploded dir first, then unpacks; a build failure means the archive itself could not be read as a valid zip. The cause BuildException is chained.","triggerScenarios":"The plugin .jpi/.hpi file is truncated, corrupt, or not a valid zip; disk I/O error mid-extract; archive was partially written by a failed download; unzipExceptClasses or createClassJarFromWebInfClasses hits a malformed central directory.","commonSituations":"Plugin downloaded over a flaky connection and saved incomplete; disk filled during write; antivirus quarantined part of the archive; manual copy of a .jpi that was still being written.","solutions":["Re-download/reinstall the plugin so the archive is complete and valid.","Verify integrity by opening the .jpi with `jar tf plugin.jpi` or `unzip -t plugin.jpi`.","Check disk space and permissions on the plugins directory.","Delete the exploded directory and the archive, then reinstall fresh."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"try (JarFile jf = new JarFile(archive)) {\n    // throws ZipException if corrupt before explode() is ever called\n    jf.stream().count();\n}","typeGuard":"null","tryCatchPattern":"try {\n    // explode\n} catch (IOException e) { // 'Failed to expand'\n    // re-download or reject the archive; do not retry the same corrupt file\n}","preventionTips":["Validate archive integrity (checksum/signature) before exploding.","Ensure downloads complete before the file is treated as a plugin.","Keep adequate free disk space for extraction."],"tags":["plugin-loading","zip","archive"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}