apache/seatunnel · error · IOException

No existing ancestor found while resolving local path ${requ

Error message

No existing ancestor found while resolving local path ${requestedPath}

What it means

While creating directories for a local path, the code walks up the path tree to find an existing ancestor so it knows which segments to create. If it reaches the filesystem root (a path with no file name or no parent) without finding any existing ancestor, it cannot determine where to start creating directories and throws an IOException with this message.

Source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/split/ContinuousMultipleTableFileSourceSplitEnumerator.java:1544

        }
        return Objects.equals(sourcePathStr, backupPathStr)
                || isParentPathQualified(sourcePathStr, backupPathStr)
                || isParentPathQualified(backupPathStr, sourcePathStr);
    }

    /**
     * Resolves the existing prefix through real paths, then appends non-existing descendants. This
     * supports a new backup directory while still detecting symlink aliases in its parent path.
     */
    private static String resolveLocalPathForOverlap(Path path) throws IOException {
        java.nio.file.Path requestedPath =
                java.nio.file.Paths.get(path.toUri()).toAbsolutePath().normalize();
        Deque<java.nio.file.Path> missingSegments = new ArrayDeque<>();
        java.nio.file.Path existingAncestor = requestedPath;
        while (!java.nio.file.Files.exists(existingAncestor)) {
            java.nio.file.Path fileName = existingAncestor.getFileName();
            if (fileName == null || existingAncestor.getParent() == null) {
                throw new IOException(
                        "No existing ancestor found while resolving local path " + requestedPath);
            }
            missingSegments.push(fileName);
            existingAncestor = existingAncestor.getParent();
        }

        java.nio.file.Path resolvedPath = existingAncestor.toRealPath();
        while (!missingSegments.isEmpty()) {
            resolvedPath = resolvedPath.resolve(missingSegments.pop());
        }
        return trimTrailingPathSeparator(resolvedPath.normalize().toString());
    }

    private static boolean isParentPathQualified(String parentPath, String childPath) {
        return childPath.startsWith(parentPath + "/");
    }

    /**

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure the parent/base directory of the requested path exists before the job runs (e.g. mkdir -p the base path).
  2. Use an absolute path that includes an existing ancestor, e.g. /data/backup instead of a bare relative name.
  3. Check container/mount configuration so the expected base directory exists where the task executes.
  4. Fix filesystem permissions so existing ancestors are visible (Files.exists should not return false due to access errors on parent dirs).

Example fix

// before
backup_path = "file://relative/backup"
// after (base dir exists on the worker)
backup_path = "file:///data/backup"
Defensive patterns

Strategy: try-catch

Validate before calling

Path p = Paths.get(requestedPath).toAbsolutePath().normalize();
if (!Files.exists(p.getParent())) {
    Files.createDirectories(p.getParent()); // or fail early with a clear message
}

Try / catch

try {
    enumerator.resolveLocalPath(requestedPath);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("No existing ancestor")) {
        log.error("Base directory for {} does not exist; create it or use an absolute path", requestedPath);
    }
    throw e;
}

Prevention

When it happens

Trigger: Resolving/creating a local directory path whose entire prefix chain (including root-level ancestors) does not exist on the local filesystem, or a degenerate/empty-normalized path where getFileName() or getParent() becomes null during the upward walk.

Common situations: Relative path resolving oddly under an unusual working directory; a path string that normalizes to root (e.g. '/' or '.'); permissions or mount issues making Files.exists() return false for all ancestors; running the task in a container where the base directory was never mounted.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/f040430637458308. Report an issue: GitHub.