apache/iceberg · error · IllegalArgumentException

Path does not start with

Error message

Path %s does not start with %s

What it means

Thrown by RewriteTablePathUtil.relativize when a path does not start with the given prefix (after appending file separators). Relativize strips the prefix to produce the relative path used under the target location; a path outside the prefix cannot be relativized.

Solutions

  1. Pass the full, exact source location as prefix so every file path starts with it.
  2. Compare the offending path in the message with the prefix and fix the prefix argument.
  3. Rewrite or relocate files stored outside the table's current location before calling the utility.

Example fix

// before
String rel = RewriteTablePathUtil.relativize(path, "s3://bucket/db"); // path is s3://bucket/warehouse/db/table/f.parquet
// after
String rel = RewriteTablePathUtil.relativize(path, "s3://bucket/warehouse/db/table");
Defensive patterns

Strategy: validation

Validate before calling

String rel = RewriteTablePathUtil.relativize(path, prefix); // pre-check:
if (!path.startsWith(prefix)) throw new IllegalArgumentException("path not under prefix: " + path);

Type guard

boolean relativizable(String path, String prefix) { String p = RewriteTablePathUtil.maybeAppendFileSeparator(path); String r = RewriteTablePathUtil.maybeAppendFileSeparator(prefix); return p.startsWith(r); }

Try / catch

try { rel = RewriteTablePathUtil.relativize(path, prefix); } catch (IllegalArgumentException e) { /* fix prefix argument */ }

Prevention

When it happens

Trigger: Any RewriteTablePathUtil newPath/relativePath call where path is not under or equal to prefix — e.g. manifest, manifest-list, or data file locations not under the supplied table prefix.

Common situations: Wrong or truncated sourcePrefix; files written by a previous table location; case-sensitive mismatch or missing trailing slash handled inconsistently.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/ef0d592d0c4f9af4. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/RewriteTablePathUtil.java:935

   * Compute the relative path from a prefix to a given path.
   *
   * <p>If the path is under the prefix, returns the portion after the prefix. If the path equals
   * the prefix (representing the root directory itself), returns an empty string.
   *
   * <p>Trailing separators are normalized: "/a" and "/a/" are treated as equivalent for both path
   * and prefix. This allows flexibility when paths come from different sources that may or may not
   * include trailing separators.
   *
   * @param path absolute path to relativize
   * @param prefix prefix path to remove
   * @return relative path from prefix to path, or empty string if path equals prefix
   * @throws IllegalArgumentException if path is not under or equal to prefix
   */
  public static String relativize(String path, String prefix) {
    String toRemove = maybeAppendFileSeparator(prefix);
    String normalizedPath = maybeAppendFileSeparator(path);
    if (!normalizedPath.startsWith(toRemove)) {
      throw new IllegalArgumentException(
          String.format("Path %s does not start with %s", normalizedPath, toRemove));
    }
    return normalizedPath.equals(toRemove) ? "" : path.substring(toRemove.length());
  }

  public static String maybeAppendFileSeparator(String path) {
    return path.endsWith(FILE_SEPARATOR) ? path : path + FILE_SEPARATOR;
  }

  /**
   * Construct a staging path under a given staging directory, preserving relative directory
   * structure to avoid conflicts when multiple files have the same name but different paths.
   *
   * @param originalPath source path
   * @param sourcePrefix source prefix to be replaced
   * @param stagingDir staging directory
   * @return a staging path under the staging directory that preserves the relative path structure
   */

View on GitHub (pinned to 86d9c8fc54)