apache/hadoop · error · IOException
"Concat operation doesn't support " + FSDirectory.DOT_RESERV
Error message
"Concat operation doesn't support " + FSDirectory.DOT_RESERVED_STRING + " relative path : " + target
What it means
The NameNode rejects concat operations whose TARGET path is a reserved path — one starting with /.reserved/raw or /.reserved/inodes. These virtual prefixes exist so clients can read raw encrypted bytes and address reserved inodes; they are read-only views, not real namespace locations, so a mutating operation like concat can never target them. The check is the first thing validatePath does before any file verification.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirConcatOp.java:87
long timestamp = now();
fsd.writeLock();
try {
unprotectedConcat(fsd, targetIIP, srcFiles, timestamp);
} finally {
fsd.writeUnlock();
}
fsd.getEditLog().logConcat(target, srcs, timestamp, logRetryCache);
return fsd.getAuditFileInfo(targetIIP);
}
private static void validatePath(String target, String[] srcs)
throws IOException {
Preconditions.checkArgument(!target.isEmpty(), "Target file name is empty");
Preconditions.checkArgument(srcs != null && srcs.length > 0,
"No sources given");
if (FSDirectory.isReservedRawName(target)
|| FSDirectory.isReservedInodesName(target)) {
throw new IOException("Concat operation doesn't support "
+ FSDirectory.DOT_RESERVED_STRING + " relative path : " + target);
}
for (String srcPath : srcs) {
if (FSDirectory.isReservedRawName(srcPath)
|| FSDirectory.isReservedInodesName(srcPath)) {
throw new IOException("Concat operation doesn't support "
+ FSDirectory.DOT_RESERVED_STRING + " relative path : " + srcPath);
}
}
}
private static void verifyTargetFile(FSDirectory fsd, final String target,
final INodesInPath targetIIP) throws IOException {
// check the target
if (FSDirEncryptionZoneOp.getEZForPath(fsd, targetIIP) != null) {
throw new HadoopIllegalArgumentException(
"concat can not be called for files in an encryption zone.");
}View on GitHub (pinned to 2add963021)
Solutions
- Strip the /.reserved/raw or /.reserved/inodes prefix from the target so it points at the real namespace path, then call concat.
- Normalize paths at the edge of your application: reject or rewrite reserved paths once, centrally, instead of per API call.
- If you genuinely need raw encrypted bytes, read via /.reserved/raw, but perform all mutations (concat, rename, delete) on the un-prefixed path.
Example fix
// before
Path target = new Path("/.reserved/raw/zone/part-0000");
fs.concat(target, srcs);
// after
Path target = new Path("/zone/part-0000"); // real namespace path
fs.concat(target, srcs); Defensive patterns
Strategy: validation
Validate before calling
static boolean isReservedPath(Path p) {
String s = p.toUri().getPath();
return s != null && (s.equals("/.reserved") || s.startsWith("/.reserved/"));
}
if (isReservedPath(target)) {
throw new IllegalArgumentException("concat target must not use /.reserved: " + target);
} Try / catch
catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("doesn't support .reserved")) {
target = stripReservedPrefix(target); // drop /.reserved/raw|inodes and retry once
fs.concat(target, srcs);
} else { throw e; }
} Prevention
- Normalize every path once at system entry: reject or rewrite /.reserved prefixes for mutating APIs.
- Keep raw paths (for reading encrypted bytes) and real paths (for concat/rename/delete) in separate, clearly typed variables or lists.
- Add a lint rule or unit test asserting no /.reserved string reaches FileSystem mutation calls.
When it happens
Trigger: Calling FileSystem.concat(target, srcs) where target still carries the /.reserved/raw prefix, typically a path that was originally obtained from an encryption-zone raw read (e.g. getFileChecksum on an encrypted file) and passed unchanged into concat.
Common situations: Backup/replication tools built for encryption zones that list files via /.reserved/raw and then feed those strings to every subsequent API; copy-pasting a raw path from a checksum or debug command into application config; downstream code that indiscriminately prefixes /.reserved/raw when an EZ is detected.
Related errors
- "Concat operation doesn't support " + FSDirectory.DOT_RESERV
- concat can not be called for files in an encryption zone.
- '{}' copy from '/.reserved/raw' to non '/.reserved/raw'. Eit
- '{}' copy from non '/.reserved/raw' to '/.reserved/raw'. Eit
- Target path not specified. <target path> <src path> <src pat
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/5882c7dd06e88056.
Report an issue: GitHub.