jenkinsci/jenkins · error · FileNotFoundException

Failed to load {}. It is not a file

Error message

Failed to load {}. It is not a file

What it means

FileNotFoundException thrown by ClassicPluginStrategy.getShortName when the archive path exists but archive.isFile() is false (it is a directory, a device, or otherwise not a regular file). Jenkins expects a single .jpi/.hpi file to read a manifest from.

Source

Thrown at core/src/main/java/hudson/ClassicPluginStrategy.java:100

    private static final Logger LOGGER = Logger.getLogger(ClassicPluginStrategy.class.getName());

    /**
     * Filter for jar files.
     */
    private static final FilenameFilter JAR_FILTER = (dir, name) -> name.endsWith(".jar");

    private final PluginManager pluginManager;

    public ClassicPluginStrategy(PluginManager pluginManager) {
        this.pluginManager = pluginManager;
    }

    @Override public String getShortName(File archive) throws IOException {
        Manifest manifest;
        if (!archive.exists()) {
            throw new FileNotFoundException("Failed to load " + archive + ". The file does not exist");
        } else if (!archive.isFile()) {
            throw new FileNotFoundException("Failed to load " + archive + ". It is not a file");
        }

        if (isLinked(archive)) {
            manifest = loadLinkedManifest(archive);
        } else {
            try (JarFile jf = new JarFile(archive, false)) {
                manifest = jf.getManifest();
            } catch (IOException ex) {
                // Mention file name in the exception
                throw new IOException("Failed to load " + archive, ex);
            }
        }
        return PluginWrapper.computeShortName(manifest, archive.getName());
    }

    private static boolean isLinked(File archive) {
        return archive.getName().endsWith(".hpl") || archive.getName().endsWith(".jpl");
    }

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Pass the packed .jpi/.hpi archive, not its expanded directory, to getShortName/createPluginWrapper.
  2. If a symlink is involved, ensure its target is a regular file.
  3. Clean up partially extracted plugin directories so only valid archives remain.
Defensive patterns

Strategy: validation

Validate before calling

File archive = new File(path);
if (!archive.isFile()) {
    throw new IllegalArgumentException(archive + " is not a regular file; pass a .jpi/.hpi archive");
}

Try / catch

try {
    strategy.getShortName(archive);
} catch (FileNotFoundException e) {
    if (e.getMessage().contains("not a file")) {
        // point the caller at the packed archive instead of the directory
    }
}

Prevention

When it happens

Trigger: The path resolves to a directory (e.g. an already-exploded plugin passed where a packed archive is required), a broken symlink, or a special file.

Common situations: An expanded plugin directory is passed as an archive; a symlink that target-checks as non-file; leftover directory from a partial extraction.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/f10ee937a12618f2. Report an issue: GitHub.