apache/hadoop · error · ExitUtil.ExitException
42
42
Error message
Filesystem is not S3A URL: {fsURI} What it means
The 'bucket' subcommand treats its single non-option argument as the URL of the bucket to create: it builds a Path, takes its URI and uses the host as the bucket name. If the URI scheme is not exactly 's3a', it exits with code 42 (EXIT_USAGE) and 'Filesystem is not S3A URL: <uri>'.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/tools/BucketTool.java:179
LOG.debug("Supplied arguments: {}", String.join(", ", args));
final List<String> parsedArgs = parseArgsWithErrorReporting(args);
CommandFormat command = getCommandFormat();
boolean create = command.getOpt(CREATE);
Optional<String> endpoint = getOptionalString(OPT_ENDPOINT);
Optional<String> region = getOptionalString(OPT_REGION);
Optional<String> zone = getOptionalString(OPT_ZONE);
final String bucketPath = parsedArgs.get(0);
final Path source = new Path(bucketPath);
URI fsURI = source.toUri();
String bucket = fsURI.getHost();
println(out, "Filesystem %s", fsURI);
if (!"s3a".equals(fsURI.getScheme())) {
throw new ExitUtil.ExitException(EXIT_USAGE, "Filesystem is not S3A URL: " + fsURI);
}
println(out, "Options region=%s endpoint=%s zone=%s s3a://%s",
region.orElse("(unset)"),
endpoint.orElse("(unset)"),
zone.orElse("(unset)"),
bucket);
if (!create) {
errorln(getUsage());
println(out, "Supplied arguments: ["
+ String.join(", ", parsedArgs)
+ "]");
throw new ExitUtil.ExitException(EXIT_USAGE,
"required option not found: -create");
}
final Configuration conf = getConf();
removeBucketOverrides(bucket, conf,View on GitHub (pinned to 2add963021)
Solutions
- Pass the fully qualified URL with the s3a scheme: 'hadoop aws s3guard bucket -create s3a://my-bucket'
- If your script holds a bare bucket name, prefix it: "s3a://$BUCKET"
- Do not substitute s3:// for s3a:// - the S3A connector only recognizes its own scheme
Example fix
# before hadoop aws s3guard bucket -create s3://my-bucket # after hadoop aws s3guard bucket -create s3a://my-bucket
Defensive patterns
Strategy: validation
Validate before calling
URI u = new Path(bucketArg).toUri();
if (!"s3a".equals(u.getScheme()) || u.getHost() == null) {
throw new IllegalArgumentException("bucket tool requires s3a://bucket URL, got: " + bucketArg);
} Try / catch
try {
int rc = new BucketTool(conf).exec(args);
} catch (ExitUtil.ExitException e) {
if (e.getExitCode() == 42 && e.getMessage().contains("not S3A URL")) {
// rewrite the argument to s3a:// form and retry once
}
} Prevention
- Normalize bucket arguments to s3a://bucket at the wrapper boundary
- Beware AWS CLI muscle memory: s3:// is never accepted by S3A tooling
When it happens
Trigger: Passing 's3://bucket' (AWS CLI habit), a bare 'bucketname' (URI with null scheme and null host), 'wasb://...' or another scheme, or a local path like '/tmp/x'; any of these fails the 's3a'.equals(scheme) check.
Common situations: Muscle memory from the AWS CLI ('aws s3 ...' uses s3://); scripts that pass just the bucket name; operators mixing HDFS or ABFS URLs into an S3 tool invocation.
Related errors
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/198eed1517985cff.
Report an issue: GitHub.