apache/flink · error · IOException

Invalid S3 URI: missing or empty bucket name in URI: {}

Error message

Invalid S3 URI: missing or empty bucket name in URI: {}

What it means

NativeS3FileSystemFactory.create derives the bucket name from the URI host (fsUri.getHost()). If the host component is null, empty, or whitespace-only (StringUtils.isNullOrWhitespaceOnly), the URI cannot identify a bucket and the factory throws IOException('Invalid S3 URI: missing or empty bucket name in URI: <uri>').

Source

Thrown at flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactory.java:442

        }

        String accessKey = config.get(ACCESS_KEY);
        String secretKey = config.get(SECRET_KEY);
        String region = config.get(REGION);
        String endpoint = config.get(ENDPOINT);
        boolean pathStyleAccess = config.get(PATH_STYLE_ACCESS);
        String sseType = config.get(SSE_TYPE);
        String sseKmsKeyId = config.get(SSE_KMS_KEY_ID);
        String assumeRoleArn = config.get(ASSUME_ROLE_ARN);
        String assumeRoleExternalId = config.get(ASSUME_ROLE_EXTERNAL_ID);
        String assumeRoleSessionName = config.get(ASSUME_ROLE_SESSION_NAME);
        int assumeRoleSessionDuration = config.get(ASSUME_ROLE_SESSION_DURATION_SECONDS);
        String credentialsProviderClasses = config.get(AWS_CREDENTIALS_PROVIDER);

        // Apply bucket-specific overrides
        String bucketName = fsUri.getHost();
        if (StringUtils.isNullOrWhitespaceOnly(bucketName)) {
            throw new IOException("Invalid S3 URI: missing or empty bucket name in URI: " + fsUri);
        }
        if (bucketConfigProvider != null) {
            S3BucketConfig overrides = bucketConfigProvider.getBucketConfig(bucketName);
            if (overrides != null) {
                LOG.debug(
                        "Applying bucket-specific configuration for bucket '{}': {}",
                        bucketName,
                        overrides);
                accessKey = firstNonNull(overrides.getAccessKey(), accessKey);
                secretKey = firstNonNull(overrides.getSecretKey(), secretKey);
                region = firstNonNull(overrides.getRegion(), region);
                endpoint = firstNonNull(overrides.getEndpoint(), endpoint);
                sseType = firstNonNull(overrides.getSseType(), sseType);
                sseKmsKeyId = firstNonNull(overrides.getSseKmsKeyId(), sseKmsKeyId);
                assumeRoleArn = firstNonNull(overrides.getAssumeRoleArn(), assumeRoleArn);
                assumeRoleExternalId =
                        firstNonNull(overrides.getAssumeRoleExternalId(), assumeRoleExternalId);
                assumeRoleSessionName =

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Include the bucket in the URI authority: s3://my-bucket/path/to/data.
  2. Validate the configured bucket variable is non-empty before building paths (fail fast at job submission with a clear message).
  3. Check for stray whitespace or '://' doubling in templated path strings.

Example fix

// before
String bucket = params.get("s3.bucket"); // null / empty
Path base = new Path("s3://" + bucket + "/data"); // s3:///data
FileSystem fs = base.getFileSystem();

// after
String bucket = Preconditions.checkNotNull(params.get("s3.bucket"), "s3.bucket must be set");
Path base = new Path("s3://" + bucket + "/data"); // s3://my-bucket/data
FileSystem fs = base.getFileSystem();
Defensive patterns

Strategy: validation

Validate before calling

static URI validateS3Uri(String scheme, String bucket, String path) {
    if (bucket == null || bucket.trim().isEmpty()) {
        throw new IllegalArgumentException("S3 bucket must be non-empty (scheme=" + scheme + ")");
    }
    return URI.create(scheme + "://" + bucket.trim() + "/" + path);
}

Try / catch

try {
    FileSystem.get(new Path(baseUri));
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("bucket name")) {
        // config produced 's3:///...': fix the missing bucket variable and resubmit
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling FileSystem.get / creating the filesystem with a URI like 's3:///', 's3:///path', 's3a://' (no host), or a URI whose host is spaces — e.g. built from an unconfigured variable that substituted to empty.

Common situations: Path strings assembled from environment variables or config placeholders where the bucket variable is unset ('s3://' + bucket + '/data' with empty bucket); typo'd schemes; programmatic URI construction that skips the authority.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/69048e761a56a128. Report an issue: GitHub.