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

  1. Add --app-root=/desired/deploy/path to the jib command
  2. Switch back to a jetty base image if the default app root is intended
  3. 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

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


AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06). Data as JSON: /api/errors/5e7d39d88a37dbb5. Report an issue: GitHub.