{"record":{"id":"69048e761a56a128","repo":"apache/flink","slug":"invalid-s3-uri-missing-or-empty-bucket-name-in-ur","errorCode":null,"errorMessage":"Invalid S3 URI: missing or empty bucket name in URI: {}","messagePattern":"Invalid S3 URI: missing or empty bucket name in URI: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactory.java","lineNumber":442,"sourceCode":"        }\n\n        String accessKey = config.get(ACCESS_KEY);\n        String secretKey = config.get(SECRET_KEY);\n        String region = config.get(REGION);\n        String endpoint = config.get(ENDPOINT);\n        boolean pathStyleAccess = config.get(PATH_STYLE_ACCESS);\n        String sseType = config.get(SSE_TYPE);\n        String sseKmsKeyId = config.get(SSE_KMS_KEY_ID);\n        String assumeRoleArn = config.get(ASSUME_ROLE_ARN);\n        String assumeRoleExternalId = config.get(ASSUME_ROLE_EXTERNAL_ID);\n        String assumeRoleSessionName = config.get(ASSUME_ROLE_SESSION_NAME);\n        int assumeRoleSessionDuration = config.get(ASSUME_ROLE_SESSION_DURATION_SECONDS);\n        String credentialsProviderClasses = config.get(AWS_CREDENTIALS_PROVIDER);\n\n        // Apply bucket-specific overrides\n        String bucketName = fsUri.getHost();\n        if (StringUtils.isNullOrWhitespaceOnly(bucketName)) {\n            throw new IOException(\"Invalid S3 URI: missing or empty bucket name in URI: \" + fsUri);\n        }\n        if (bucketConfigProvider != null) {\n            S3BucketConfig overrides = bucketConfigProvider.getBucketConfig(bucketName);\n            if (overrides != null) {\n                LOG.debug(\n                        \"Applying bucket-specific configuration for bucket '{}': {}\",\n                        bucketName,\n                        overrides);\n                accessKey = firstNonNull(overrides.getAccessKey(), accessKey);\n                secretKey = firstNonNull(overrides.getSecretKey(), secretKey);\n                region = firstNonNull(overrides.getRegion(), region);\n                endpoint = firstNonNull(overrides.getEndpoint(), endpoint);\n                sseType = firstNonNull(overrides.getSseType(), sseType);\n                sseKmsKeyId = firstNonNull(overrides.getSseKmsKeyId(), sseKmsKeyId);\n                assumeRoleArn = firstNonNull(overrides.getAssumeRoleArn(), assumeRoleArn);\n                assumeRoleExternalId =\n                        firstNonNull(overrides.getAssumeRoleExternalId(), assumeRoleExternalId);\n                assumeRoleSessionName =","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactory.java#L424-L460","documentation":"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>').","triggerScenarios":"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.","commonSituations":"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.","solutions":["Include the bucket in the URI authority: s3://my-bucket/path/to/data.","Validate the configured bucket variable is non-empty before building paths (fail fast at job submission with a clear message).","Check for stray whitespace or '://' doubling in templated path strings."],"exampleFix":"// before\nString bucket = params.get(\"s3.bucket\"); // null / empty\nPath base = new Path(\"s3://\" + bucket + \"/data\"); // s3:///data\nFileSystem fs = base.getFileSystem();\n\n// after\nString bucket = Preconditions.checkNotNull(params.get(\"s3.bucket\"), \"s3.bucket must be set\");\nPath base = new Path(\"s3://\" + bucket + \"/data\"); // s3://my-bucket/data\nFileSystem fs = base.getFileSystem();","handlingStrategy":"validation","validationCode":"static URI validateS3Uri(String scheme, String bucket, String path) {\n    if (bucket == null || bucket.trim().isEmpty()) {\n        throw new IllegalArgumentException(\"S3 bucket must be non-empty (scheme=\" + scheme + \")\");\n    }\n    return URI.create(scheme + \"://\" + bucket.trim() + \"/\" + path);\n}","typeGuard":null,"tryCatchPattern":"try {\n    FileSystem.get(new Path(baseUri));\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"bucket name\")) {\n        // config produced 's3:///...': fix the missing bucket variable and resubmit\n    } else {\n        throw e;\n    }\n}","preventionTips":["Validate bucket variables are set before assembling s3:// URIs from templates.","Write a unit test that asserts constructed URIs have a non-empty host.","Watch for empty-string substitution from environment variables in deploy pipelines."],"tags":["s3","uri-parsing","configuration","validation"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}