apache/seatunnel · warning
The S3A credentials provider class '{}' configured via '{}'
Error message
The S3A credentials provider class '{}' configured via '{}' could not be fully validated on this node because the provider class or '{}' is not visible through the available classloaders. The job will fail at runtime unless the provider jar is available on every node running the S3A filesystem (for example under ${SEATUNNEL_HOME}/lib). What it means
SeaTunnel's S3 file connector validates at configuration time that any custom S3A credentials provider class (fs.s3a.aws.credentials.provider) can be loaded and actually implements org.apache.hadoop.fs.s3a.auth.CredentialsProvider. When neither the provider class nor the CredentialsProvider interface is visible through any of the available classloaders, the check cannot run on this node, so it only logs a warning instead of failing fast. The job may still fail at runtime on any node where the provider jar is missing from the S3A filesystem's classpath.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-s3/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/s3/config/S3HadoopConf.java:188
for (ClassLoader classLoader : credentialsProviderClassLoaders()) {
if (classLoader == null) {
continue;
}
Class<?> providerClass;
Class<?> providerInterface;
try {
providerClass = Class.forName(providerClassName, false, classLoader);
providerInterface =
Class.forName(AWS_CREDENTIALS_PROVIDER_INTERFACE, false, classLoader);
} catch (ClassNotFoundException ignored) {
// Both classes must resolve through the same loader before assignability can be
// checked. Try the next loader instead of treating a skipped check as success.
continue;
}
assertImplementsCredentialsProvider(providerClass, providerInterface);
return;
}
LOGGER.warn(
"The S3A credentials provider class '{}' configured via '{}' could not be fully "
+ "validated on this node because the provider class or '{}' is not visible "
+ "through the available classloaders. The job will fail at runtime unless "
+ "the provider jar is available on every node running the S3A filesystem "
+ "(for example under ${SEATUNNEL_HOME}/lib).",
providerClassName,
S3FileBaseOptions.S3A_AWS_CREDENTIALS_PROVIDER_CLASS.key(),
AWS_CREDENTIALS_PROVIDER_INTERFACE);
}
/**
* Asserts the resolved provider class can actually be used by Hadoop S3A: it must implement
* {@link #AWS_CREDENTIALS_PROVIDER_INTERFACE} and must not be abstract. These are exactly the
* two conditions {@code S3AUtils.createAWSCredentialProvider} enforces before instantiation, so
* this check never rejects a class Hadoop would have accepted — it only surfaces the failure at
* config-parse time with an actionable message instead of an opaque worker-side error.
*
* <p>The caller resolves both classes through the same candidate classloader. If either classView on GitHub (pinned to cf67b549a7)
Solutions
- Place the jar containing the credentials provider class (and its dependencies) in ${SEATUNNEL_HOME}/lib on EVERY node that runs the S3A filesystem, then restart the nodes.
- If the provider should always be available, verify the configured class name is correct (fully qualified, correct spelling) so it can be found and validated.
- If the provider is intentionally not on this node, accept the warning but ensure runtime classpath coverage, or pre-validate by loading the class yourself before submitting the job.
- As a fallback, use a built-in provider (e.g. com.amazonaws.auth.EnvironmentVariableCredentialsProvider, ProfileCredentialsProvider) that is already visible to the connector's classloaders.
Example fix
// before (provider jar only on some nodes)
S3Config: { "fs.s3a.aws.credentials.provider": "com.custom.MyCredentialsProvider" }
// after (jar deployed to every node)
cp my-credentials-provider.jar ${SEATUNNEL_HOME}/lib/ # run on ALL worker nodes, then restart Defensive patterns
Strategy: validation
Validate before calling
try {
Class<?> provider = Class.forName(providerClassName, false, getClass().getClassLoader());
if (!org.apache.hadoop.fs.s3a.auth.CredentialsProvider.class.isAssignableFrom(provider)) {
throw new IllegalArgumentException(providerClassName + " does not implement CredentialsProvider");
}
} catch (ClassNotFoundException e) {
// jar is missing from this node's classpath — deploy it to ${SEATUNNEL_HOME}/lib on all nodes
} Type guard
boolean isValidCredentialsProvider(String className) {
try {
return Class.forName(className, false, Thread.currentThread().getContextClassLoader())
.isAssignableFrom(org.apache.hadoop.fs.s3a.auth.CredentialsProvider.class)
|| org.apache.hadoop.fs.s3a.auth.CredentialsProvider.class
.isAssignableFrom(Class.forName(className, false, Thread.currentThread().getContextClassLoader()));
} catch (ClassNotFoundException | NoClassDefFoundError e) {
return false;
}
} Prevention
- Deploy the credentials-provider jar to ${SEATUNNEL_HOME}/lib on every node, not just the submit client.
- Use fully qualified provider class names and verify spelling against the jar's contents (jar tf).
- Prefer built-in S3A providers (env vars, profile, instance profile) when a custom class is not strictly required.
- Keep ${SEATUNNEL_HOME}/lib synchronized across the cluster as part of your deployment procedure.
When it happens
Trigger: A user sets an S3A credentials provider class name in the S3 config (e.g. com.custom.MyProvider or a provider from a Hadoop/AWS jar) and that jar is not on the classpath visible to the connector's classloaders — e.g. the jar exists on the client/coordinator node but not on worker nodes, or it is not placed under ${SEATUNNEL_HOME}/lib so plugin classloaders cannot see it.
Common situations: Custom AWSCredentialsProvider implementations shipped only with the job jar; provider classes from a Hadoop version that differs from the shaded Hadoop SeaTunnel uses; cluster upgrades where ${SEATUNNEL_HOME}/lib was not synced across all nodes; running in clustered Zeta mode where only some workers have the provider jar.
Related errors
- Hadoop found on classpath but could not create config, proce
- Circular condition chain detected: '%s' already exists in th
- Condition for option '%s' has a null operator
- Could not find any factories that implement '%s' in the clas
- Multiple factories for identifier '%s' that implement '%s' f
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/e9dc06f88662ebde.
Report an issue: GitHub.