apache/seatunnel · error · IOException
Cannot rename %s under itself : %s
Error message
Cannot rename %s under itself : %s
What it means
rename() guards against a degenerate move: if the destination path lies underneath the source path (isParentOf(absoluteSrc, absoluteDst)), moving a directory into itself is impossible, so it throws a plain IOException 'Cannot rename %s under itself : %s'.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:845
* @throws IOException IOException
*/
private boolean rename(FTPClient client, Path src, Path dst) throws IOException {
Path workDir = new Path(client.printWorkingDirectory());
Path absoluteSrc = makeAbsolute(workDir, src);
Path absoluteDst = makeAbsolute(workDir, dst);
if (!exists(client, absoluteSrc)) {
throw new FileNotFoundException("Source path " + src + " does not exist");
}
if (isDirectory(absoluteDst)) {
// destination is a directory: rename goes underneath it with the
// source name
absoluteDst = new Path(absoluteDst, absoluteSrc.getName());
}
if (exists(client, absoluteDst)) {
throw new FileAlreadyExistsException("Destination path " + dst + " already exists");
}
if (isParentOf(absoluteSrc, absoluteDst)) {
throw new IOException(
"Cannot rename " + absoluteSrc + " under itself" + " : " + absoluteDst);
}
String from = absoluteSrc.toUri().getPath();
String to = absoluteDst.toUri().getPath();
return client.rename(from, to);
}
@Override
public Path getWorkingDirectory() {
// Return home directory always since we do not maintain state.
return getHomeDirectory();
}
@Override
public Path getHomeDirectory() {
FTPClient client = null;
try {
client = connect();View on GitHub (pinned to cf67b549a7)
Solutions
- Fix the destination path computation so dst is not inside src
- Move the source to a sibling/temp path first, then relocate it to the final nested location in two steps
- Review config that derives the output path from the input path; add an assert src is not an ancestor of dst before calling rename
Example fix
// before
fs.rename(new Path("/data"), new Path("/data/archive/data")); // invalid
// after
Path src = new Path("/data");
Path dst = new Path("/data-new"); // sibling, not a descendant
fs.rename(src, dst); Defensive patterns
Strategy: validation
Validate before calling
// Java: reject nested rename before calling the API
Path src = new Path("/data");
Path dst = new Path("/data/archive");
if (dst.toString().startsWith(src.toString() + "/")) {
throw new IllegalArgumentException("Cannot rename "+src+" under itself");
} Try / catch
try {
fs.rename(src, dst);
} catch (IOException e) {
if (e.getMessage().contains("under itself")) {
logger.error("Path construction bug: dst is inside src");
}
} Prevention
- Assert dst is not a descendant of src before renaming
- Avoid deriving output paths by concatenation onto the input directory
- Use sibling temp directories for staging
When it happens
Trigger: rename(client, src, dst) where absoluteDst is a subpath of absoluteSrc — e.g. renaming '/data' to '/data/archive/data' or renaming a dir to a path inside itself.
Common situations: Programmatic path construction bug where the output directory is computed from the input directory; misconfigured staging dir located inside the directory being renamed; recursive backup logic that nests the source under its own child.
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
- Source path %s does not exist
- Destination path %s already exists
- Illegal format [%s]
- Unknown ftp connection mode: ${mode}
- Invalid host specified
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/e8e5d0aa89512712.
Report an issue: GitHub.