apache/hadoop · error · PathIOException
Can't create root path
Error message
Can't create root path
What it means
innerCreateFile() converts the target Path to an S3 object key with pathToKey(); the filesystem root (s3a://bucket/ or /) maps to the empty string, and S3 has no zero-length object key. So any create whose path resolves to the bucket root fails immediately with PathIOException on path '/' before any create flag is examined - neither overwrite, performance nor conditional options bypass it.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java:2100
* If true, this method call does no IO at all.
* @param path the file name to open
* @param progress the progress reporter.
* @param auditSpan audit span
* @param options options for the file
* @throws IOException in the event of IO related errors.
*/
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
@Retries.RetryTranslated
private FSDataOutputStream innerCreateFile(
final Path path,
final Progressable progress,
final AuditSpan auditSpan,
final CreateFileBuilder.CreateFileOptions options) throws IOException {
auditSpan.activate();
String key = pathToKey(path);
if (key.isEmpty()) {
// no matter the creation options, root cannot be written to.
throw new PathIOException("/", "Can't create root path");
}
EnumSet<CreateFlag> flags = options.getFlags();
/*
Calculate whether to perform HEAD/LIST checks,
and whether the conditional create option should be set.
This seems complicated, but comes down to
"if explicitly requested and the FS enables it, use".
*/
// create file attributes
boolean cCreate = options.isConditionalOverwrite();
boolean cEtag = options.isConditionalOverwriteEtag();
boolean createPerf = options.isPerformance();
boolean overwrite = flags.contains(CreateFlag.OVERWRITE);
// path attributes
boolean magic = isUnderMagicCommitPath(path);
View on GitHub (pinned to 2add963021)
Solutions
- Fix the caller to pass a path with a real, non-empty last component (the object key)
- Validate that path.getName() / the configured filename is non-empty before calling create
- Log the exact path at the call site so mis-built paths surface immediately
Example fix
// before
fs.create(new Path("s3a://" + bucket + "/" + fileName));
// after: reject blank names before touching S3A
if (fileName == null || fileName.trim().isEmpty()) {
throw new IllegalArgumentException("fileName must not be empty");
}
fs.create(new Path(new Path("s3a://" + bucket + "/"), fileName)); Defensive patterns
Strategy: validation
Validate before calling
static Path requireFileTarget(Path p) {
if (p.isRoot() || p.toUri().getPath().equals("/")) {
throw new IllegalArgumentException("Refusing to create at filesystem root: " + p);
}
return p;
} Try / catch
If paths arrive from frameworks and cannot be pre-checked, catch PathIOException from create(), inspect getPath() and the message, and map 'Can't create root path' to an input-validation error rather than a retriable failure.
Prevention
- Build paths with new Path(parent, child), never string concatenation of unvalidated parts
- Reject blank output filenames at the CLI/config layer
- Assert !path.isRoot() in test fixtures that create files
When it happens
Trigger: fs.create(new Path("s3a://bucket/")) or create(new Path("/")); building a Path from a blank or missing filename; concatenating a parent string with a null child element so the result normalizes to the root.
Common situations: Paths assembled from unvalidated user or config input where the output filename is empty; walking getParent() one level too far; a blank output-file property making the job write to the bucket root.
Related errors
- source is root directory
- dest is root directory
- Conditional Writes Unavailable
- <path> is a directory
- <path> already exists
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/21e8282499864da8.
Report an issue: GitHub.