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 : " + srcPath
What it means
Identical guard to the target-path check, but applied to each SOURCE path: concat refuses any src under /.reserved/raw or /.reserved/inodes. validatePath loops over every element of srcs and throws before target/source file verification begins. The rationale is the same — reserved paths are virtual views and cannot participate in namespace mutation.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirConcatOp.java:93
}
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.");
}
final INodeFile targetINode = INodeFile.valueOf(targetIIP.getLastINode(),
target);
if(targetINode.isUnderConstruction()) {
throw new HadoopIllegalArgumentException("concat: target file "
+ target + " is under construction");
}View on GitHub (pinned to 2add963021)
Solutions
- Strip the reserved prefix from every source path before calling concat (map the srcs array through a normalizer).
- Keep two distinct path lists in EZ tooling: raw paths for reading bytes, plain paths for mutations — never interchange them.
- Add a unit assertion in your pipeline that no path passed to a mutating FileSystem API starts with /.reserved.
Example fix
// before
Path[] srcs = rawManifest.stream().map(Path::new).toArray(Path[]::new);
fs.concat(target, srcs);
// after
Path[] srcs = rawManifest.stream()
.map(p -> new Path(p).toUri().getPath().replaceFirst("^/\\.reserved/(raw|inodes)", ""))
.map(Path::new).toArray(Path[]::new);
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/"));
}
for (Path src : srcs) {
if (isReservedPath(src)) throw new IllegalArgumentException("strip /.reserved from src: " + src);
} Try / catch
catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("doesn't support .reserved")) {
srcs = Arrays.stream(srcs).map(p -> stripReserved(p)).toArray(Path[]::new);
fs.concat(target, srcs); // retry with cleaned sources
} else { throw e; }
} Prevention
- Sanitize whole src arrays in one place before any mutating call, not per call site.
- Never feed a manifest produced by /.reserved/raw listings directly into concat; map raw paths to plain paths explicitly.
- Log the exact src list at DEBUG before concat so offending paths are identifiable on failure.
When it happens
Trigger: Calling FileSystem.concat(target, srcs) where one or more entries in srcs contain the /.reserved/raw prefix — e.g. a manifest of raw paths produced by an encryption-zone-aware listing tool is fed straight into concat.
Common situations: Ingest pipelines that list an encryption zone through /.reserved/raw for verification and then reuse the same path list for compaction via concat; mixed toolchains where one component adds the prefix and another (correctly) does not.
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/f7a7df94faade6b9.
Report an issue: GitHub.