GoogleContainerTools/jib · error · IllegalArgumentException
Please set the app root of the container with `--app-root` w
Error message
Please set the app root of the container with `--app-root` when specifying a base image that is not jetty.
What it means
When building from a WAR, the default app root (/var/jetty/webapps or similar) only applies to jetty-based base images. If the selected base image is not jetty and --app-root was not provided, ArtifactProcessors.fromWar() throws IllegalArgumentException because the deploy path would be wrong for that base image.
Source
Thrown at jib-cli/src/main/java/com/google/cloud/tools/jib/cli/ArtifactProcessors.java:107
/**
* Creates a {@link ArtifactProcessor} instance.
*
* @param warPath path to the war
* @param cacheDirectories the location of the relevant caches
* @param warOptions war cli options
* @param commonContainerConfigCliOptions common cli options shared between jar and war command
* @return ArtifactProcessor
* @throws InvalidImageReferenceException if base image reference is invalid
*/
public static ArtifactProcessor fromWar(
Path warPath,
CacheDirectories cacheDirectories,
War warOptions,
CommonContainerConfigCliOptions commonContainerConfigCliOptions)
throws InvalidImageReferenceException {
Optional<AbsoluteUnixPath> appRoot = warOptions.getAppRoot();
if (!commonContainerConfigCliOptions.isJettyBaseimage() && !appRoot.isPresent()) {
throw new IllegalArgumentException(
"Please set the app root of the container with `--app-root` when specifying a base image that is not jetty.");
}
AbsoluteUnixPath chosenAppRoot = appRoot.orElse(AbsoluteUnixPath.get(DEFAULT_JETTY_APP_ROOT));
return new StandardWarExplodedProcessor(
warPath, cacheDirectories.getExplodedArtifactDirectory(), chosenAppRoot);
}
/**
* Determines whether the jar is a spring boot or standard jar.
*
* @param jarPath path to the jar
* @return the jar type
* @throws IOException if I/O error occurs when opening the file
*/
private static String determineJarType(Path jarPath) throws IOException {
try (JarFile jarFile = new JarFile(jarPath.toFile())) {
if (jarFile.getEntry("BOOT-INF") != null) {
return SPRING_BOOT;View on GitHub (pinned to fb949e2676)
Solutions
- Add --app-root=/desired/deploy/path to the jib command
- Switch back to a jetty base image if the default app root is intended
- Set the app root programmatically via warOptions.setAppRoot(AbsoluteUnixPath.get("/..."))
Example fix
// before jib war --from=tomcat:10 --target=gcr.io/project/app app.war // after jib war --from=tomcat:10 --app-root=/usr/local/tomcat/webapps/ROOT --target=gcr.io/project/app app.war
Defensive patterns
Strategy: validation
Validate before calling
if (!"jetty".contains(fromImage.toLowerCase()) && appRoot == null) { /* require --app-root */ } Try / catch
try { processor.fromWar(warPath, ...); } catch (IllegalArgumentException e) { /* re-run with --app-root set */ } Prevention
- Always pass --app-root when using a non-jetty base image for WARs
- Centralize jib CLI invocation defaults so --from changes come with --app-root
- Prefer jetty base images unless a custom app root is configured
When it happens
Trigger: Running `jib war app.war` with a non-jetty --from base image and no --app-root option.
Common situations: Switching to a Tomcat or distroless base image for a WAR while keeping jib-cli's jetty defaults; forgetting --app-root after changing --from.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- The input JAR (${jarPath}) is compiled with Java ${jarJavaVe
- The class file (${jarEntry}) is of an invalid format.
- Reached end of class file (${jarEntry}) before being able to
- Only FileLayers are supported at this time.
- Computing the entrypoint is currently not supported.
AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06).
Data as JSON: /api/errors/5e7d39d88a37dbb5.
Report an issue: GitHub.