jenkinsci/jenkins · error · IOException
jenkins.war location is not known.
Error message
jenkins.war location is not known.
What it means
Thrown by Lifecycle.rewriteHudsonWar(File) when getHudsonWar() returns null. This base implementation is used to overwrite jenkins.war during an in-place upgrade. A null war path means Jenkins could not determine where its own war file lives. The code comment notes this should be impossible if canRewriteHudsonWar() was honored, hence it is a defensive guard.
Source
Thrown at core/src/main/java/hudson/lifecycle/Lifecycle.java:169
String war = SystemProperties.getString("executable-war");
if (war != null && new File(war).exists())
return new File(war);
return null;
}
/**
* Replaces jenkins.war by the given file.
*
* <p>
* On some system, most notably Windows, a file being in use cannot be changed,
* so rewriting {@code jenkins.war} requires some special trick. Override this method
* to do so.
*/
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 it gets lost due to upgrading
// (newly downloaded jenkins.war and 'backup' (jenkins.war.tmp) are the same files
// 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);
FileUtils.copyFile(by, dest);
// we don't want to keep backup if we are downgrading
if (by.equals(bak)) {
Files.deleteIfExists(Util.fileToPath(bak));
}
}
/**
* Can {@link #rewriteHudsonWar(File)} work?
*/View on GitHub (pinned to 2e228ff40b)
Solutions
- Run Jenkins from the actual jenkins.war file so the war location is resolvable
- If using a servlet container, perform upgrades by redeploying the war via the container, not via Jenkins' restart API
- Check that the war location system property / launch argument is set correctly
- Avoid calling the in-place upgrade API in environments without a physical war file
Defensive patterns
Strategy: validation
Validate before calling
Lifecycle lc = Lifecycle.get();
if (lc.getHudsonWar() == null) {
throw new IllegalStateException("No jenkins.war location; in-place upgrade is not available in this mode");
} Try / catch
try {
Lifecycle.get().rewriteHudsonWar(newWar);
} catch (IOException e) {
if (e.getMessage().contains("jenkins.war location is not known")) {
// cannot do in-place upgrade here; redeploy externally
}
throw e;
} Prevention
- Run Jenkins from the physical jenkins.war so getHudsonWar() resolves
- For servlet-container deployments, use the container's redeploy mechanism instead
- Check canRewriteHudsonWar() semantics before calling rewriteHudsonWar
When it happens
Trigger: An upgrade or downgrade path calls rewriteHudsonWar(by); getHudsonWar() returns null because the war location was never set (e.g. launched from an exploded classpath or a custom main that does not set the war file).
Common situations: Running Jenkins from an IDE or exploded webapp where there is no jenkins.war on disk; deploying under a servlet container (Tomcat) where the war identity differs; a custom launcher that does not populate the war location.
Related errors
- jenkins.war location is not known.
- Default Windows lifecycle does not support restart.
- Failed to install embedded lifecycle implementation, so cann
- Restart is not supported in this running mode ({getClass().g
- {} doesn't extend from hudson.Plugin
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/564fbe8e2ea78459.
Report an issue: GitHub.