{"record":{"id":"d0a9595a250c3959","repo":"apache/flink","slug":"fs-s3-aws-credentials-provider-is-set-but-contains","errorCode":null,"errorMessage":"fs.s3.aws.credentials.provider is set but contains no valid provider class names","messagePattern":"fs\\.s3\\.aws\\.credentials\\.provider is set but contains no valid provider class names","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/S3ClientProvider.java","lineNumber":887,"sourceCode":"            return \"CRT transport requested (s3.crt.enabled=true) but the aws-crt JAR \"\n                    + \"is not on the classpath. Place it in the Flink plugin directory \"\n                    + \"(e.g. $FLINK_HOME/plugins/s3-fs-native/) alongside flink-s3-fs-native.jar. \"\n                    + \"Run tools/download-crt-jars.sh to download the matching version. \"\n                    + \"See the module README for setup details.\";\n        }\n\n        private AwsCredentialsProvider buildBaseCredentialsProvider() {\n            List<AwsCredentialsProvider> chain = new ArrayList<>();\n\n            if (!StringUtils.isNullOrWhitespaceOnly(credentialsProviderClasses)) {\n                for (String name : credentialsProviderClasses.split(\",\")) {\n                    String trimmed = name.trim();\n                    if (!trimmed.isEmpty()) {\n                        chain.add(instantiateCredentialsProvider(trimmed));\n                    }\n                }\n                if (chain.isEmpty()) {\n                    throw new IllegalArgumentException(\n                            \"fs.s3.aws.credentials.provider is set but contains no valid provider class names\");\n                }\n            }\n\n            if (accessKey != null && secretKey != null) {\n                chain.add(\n                        StaticCredentialsProvider.create(\n                                AwsBasicCredentials.create(accessKey, secretKey)));\n            }\n\n            chain.add(new DynamicTemporaryAWSCredentialsProvider());\n            chain.add(DefaultCredentialsProvider.builder().build());\n\n            LOG.info(\n                    \"Using credentials provider chain: {}\",\n                    chain.stream()\n                            .map(p -> p.getClass().getSimpleName())\n                            .collect(Collectors.joining(\" -> \")));","sourceCodeStart":869,"sourceCodeEnd":905,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/S3ClientProvider.java#L869-L905","documentation":"buildBaseCredentialsProvider() parses fs.s3.aws.credentials.provider as a comma-separated list of provider class names. After trimming and dropping empty entries, if NO entry survived the chain stays empty and this IllegalArgumentException is thrown — i.e. the option's value consists only of whitespace/commas (e.g. \" \", \",,\", \" , \"). A single invalid class name throws a different error (class resolution / instantiation), so this one specifically means zero usable names were parsed.","triggerScenarios":"flink-conf.yaml contains fs.s3.aws.credentials.provider with an empty or comma-only value: fs.s3.aws.credentials.provider: (blank), : \",\", : \" , , \". Any filesystem/client construction at plugin init fails immediately.","commonSituations":"YAML templating (Helm/Kustomize) that renders an unset variable as empty string; commented-out examples partially reverted; copy-paste of a placeholder value like 'COMMA_SEPARATED_LIST'; trailing colon with no value in flink-conf.yaml which Flink parses as empty string.","solutions":["Set the option to at least one valid provider class name, e.g. fs.s3.aws.credentials.provider: org.apache.flink.fs.s3native.user.TemporaryKeyCredentialsProvider, or remove the line entirely to use the default chain (static keys, DynamicTemporaryAWSCredentialsProvider, DefaultCredentialsProvider).","Check rendered config on the cluster: grep 'credentials.provider' flink-conf.yaml* and fix templating that emits blank values.","If multiple providers are wanted, supply them comma-separated with real names: 'A,B'."],"exampleFix":"# before (flink-conf.yaml)\nfs.s3.aws.credentials.provider:\n\n# after (either remove the line, or set a real provider)\nfs.s3.aws.credentials.provider: software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider","handlingStrategy":"validation","validationCode":"// Validate the option before Flink initializes the filesystem\nString providers = conf.getString(\"fs.s3.aws.credentials.provider\", \"\");\nboolean hasName = Arrays.stream(providers.split(\",\")).map(String::trim).anyMatch(s -> !s.isEmpty());\nif (providers != null && !providers.trim().isEmpty() && !hasName) {\n    throw new IllegalArgumentException(\"fs.s3.aws.credentials.provider must list at least one class name\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint rendered flink-conf.yaml in CI: fail when an s3.* key has an empty value.","Prefer omitting the option entirely over setting it blank.","When templating configs, render the whole line conditionally, not just the value."],"tags":["configuration","credentials","s3","flink-conf","flink"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}