apache/seatunnel · error · IllegalArgumentException

The S3A credentials provider class

Error message

The S3A credentials provider class '%s' does not implement '%s'. Please check the value of '%s' and configure a class that implements the AWS credentials provider contract.

What it means

Thrown by S3HadoopConf when validating the configured S3A credentials provider class. The library reflects on the class named by the S3A AWS credentials provider option and requires it to implement the AWS credentials provider contract (AWSCredentialsProvider / AWSCredentialsProviderV2); if isAssignableFrom fails, it throws this IllegalArgumentException so misconfiguration fails fast instead of at S3 connection time.

Solutions

  1. Check the config value and set it to a fully qualified class that implements com.amazonaws.auth.AWSCredentialsProvider (or the V2 interface the connector expects), e.g. com.amazonaws.auth.EnvironmentVariableCredentialsProvider
  2. Verify the class is on the connector/plugin classpath (it must load via the connector classloader) and that the FQCN is spelled exactly, no leading/trailing spaces
  3. If you have a custom wrapper, make it implement AWSCredentialsProvider directly instead of delegating without implementing
  4. Rebuild/redeploy the connector with the shaded AWS SDK matching the provider interface you implement

Example fix

// before
s3.aws.credentials-provider-class = "com.example.MyProviderHelper" // does not implement AWSCredentialsProvider
// after
s3.aws.credentials-provider-class = "com.amazonaws.auth.EnvironmentVariableCredentialsProvider"
Defensive patterns

Strategy: validation

Validate before calling

String cls = conf.get("s3a.aws.credentials-provider-class");
Class<?> c = Class.forName(cls);
if (!com.amazonaws.auth.AWSCredentialsProvider.class.isAssignableFrom(c))
    throw new IllegalArgumentException(cls + " must implement AWSCredentialsProvider");

Prevention

When it happens

Trigger: S3FileBaseOptions.S3A_AWS_CREDENTIALS_PROVIDER_CLASS is set to a class that either does not implement AWSCredentialsProvider/V2 at all, or whose fully qualified name was resolved to the wrong class by checkCredentialsProviderClass's dual classloader lookup (context + connector classloader).

Common situations: Typo or stale fully-qualified class name in config; pointing the option at a helper class that wraps (but does not implement) AWSCredentialsProvider; picking a provider from a different AWS SDK major version (v1 vs v2 provider interfaces) than the connector shades; copy-pasting a Hadoop s3a provider class that doesn't exist on the connector classpath so a similarly-named wrong class loads.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/9330c8269dc0079d. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-s3/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/s3/config/S3HadoopConf.java:213

                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 class
     * is unavailable it tries the next loader, so an isolated thread context classloader cannot
     * bypass validation when the connector classloader can perform it.
     */
    private static void assertImplementsCredentialsProvider(
            Class<?> providerClass, Class<?> providerInterface) {
        if (!providerInterface.isAssignableFrom(providerClass)) {
            throw new IllegalArgumentException(
                    String.format(
                            "The S3A credentials provider class '%s' does not implement '%s'. "
                                    + "Please check the value of '%s' and configure a class that "
                                    + "implements the AWS credentials provider contract.",
                            providerClass.getName(),
                            AWS_CREDENTIALS_PROVIDER_INTERFACE,
                            S3FileBaseOptions.S3A_AWS_CREDENTIALS_PROVIDER_CLASS.key()));
        }
        if (Modifier.isAbstract(providerClass.getModifiers())) {
            throw new IllegalArgumentException(
                    String.format(
                            "The S3A credentials provider class '%s' configured via '%s' is "
                                    + "abstract and cannot be instantiated. Please configure a "
                                    + "concrete AWS credentials provider class.",
                            providerClass.getName(),
                            S3FileBaseOptions.S3A_AWS_CREDENTIALS_PROVIDER_CLASS.key()));
        }
    }

View on GitHub (pinned to cf67b549a7)