jenkinsci/jenkins · error · IOException

jenkins.war location is not known.

Error message

jenkins.war location is not known.

What it means

Thrown by WindowsServiceLifecycle.rewriteHudsonWar(File) when getHudsonWar() returns null. Identical defensive guard as the base Lifecycle.rewriteHudsonWar, but in the Windows context the war is locked while the service runs, so the method writes the new war to a special name (.copies mechanism) for the service wrapper to pick up on restart. A null war path short-circuits before that mechanism runs.

Source

Thrown at core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java:101

                    LOGGER.log(Level.SEVERE, "Failed to replace " + name, e);
                } catch (InterruptedException e) {
                }
            }
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "Failed to replace jenkins.exe", e);
        }
    }

    /**
     * On Windows, jenkins.war is locked, so we place a new version under a special name,
     * which is picked up by the service wrapper upon restart.
     */
    @Override
    public void rewriteHudsonWar(File by) throws IOException {
        File dest = getHudsonWar();
        // this should be impossible given the canRewriteHudsonWar method,
        // but let's be defensive
        if (dest == null)  throw new IOException("jenkins.war location is not known.");

        // backing up the old jenkins.war before its lost due to upgrading
        // unless we are trying to rewrite jenkins.war by a backup itself
        File bak = new File(dest.getPath() + ".bak");
        if (!by.equals(bak))
            FileUtils.copyFile(dest, bak);

        String baseName = dest.getName();
        baseName = baseName.substring(0, baseName.indexOf('.'));

        File baseDir = getBaseDir();
        File copyFiles = new File(baseDir, baseName + ".copies");

        try (Writer w = Files.newBufferedWriter(Util.fileToPath(copyFiles), Charset.defaultCharset(), StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
            w.write(by.getAbsolutePath() + '>' + getHudsonWar().getAbsolutePath() + '\n');
        }
    }

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Verify the Jenkins service is installed from the standard jenkins.war so the path is resolvable
  2. Check the service wrapper configuration (jenkins.xml) for the correct war path
  3. Perform upgrades via the service wrapper's own mechanism rather than the in-process rewrite API
  4. Ensure getHudsonWar() returns non-null by launching from the actual war file
Defensive patterns

Strategy: validation

Validate before calling

Lifecycle lc = Lifecycle.get();
if (lc.getHudsonWar() == null) {
    throw new IllegalStateException("jenkins.war not resolvable in this Windows service deployment");
}

Try / catch

try {
    Lifecycle.get().rewriteHudsonWar(newWar);
} catch (IOException e) {
    if (e.getMessage().contains("jenkins.war location is not known")) {
        // redeploy via the service wrapper instead
    }
    throw e;
}

Prevention

When it happens

Trigger: Jenkins running as a Windows service; an upgrade path calls rewriteHudsonWar(by); getHudsonWar() returns null because the war location is not resolvable in this service deployment.

Common situations: Service installed in a non-standard layout where the war path is not registered; custom service wrapper that does not expose the war location; a repackaged war deployed under a different name.

Related errors


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