apache/iceberg · error · IllegalArgumentException

Cannot initialize TLSConfigurer implementation %s: %s

Error message

Cannot initialize TLSConfigurer implementation %s: %s

What it means

When configuring custom TLS via the REST client's tls-implementation property, HTTPClient loads the implementation class reflectively with DynConstructors. If the class cannot be found or has no usable no-arg constructor (NoSuchMethodException), it throws IllegalArgumentException with this message. This is a configuration/classpath problem, not a TLS handshake failure.

Source

Thrown at core/src/main/java/org/apache/iceberg/rest/HTTPClient.java:452

    return connectionManagerBuilder.build();
  }

  private static TLSConfigurer loadTlsConfigurer(Map<String, String> properties) {
    String impl = properties.get(REST_TLS_CONFIGURER);
    if (impl == null) {
      return null;
    }

    DynConstructors.Ctor<TLSConfigurer> ctor;
    try {
      ctor =
          DynConstructors.builder(TLSConfigurer.class)
              .loader(HTTPClient.class.getClassLoader())
              .impl(impl)
              .buildChecked();
    } catch (NoSuchMethodException e) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot initialize TLSConfigurer implementation %s: %s", impl, e.getMessage()),
          e);
    }

    TLSConfigurer configurer;
    try {
      configurer = ctor.newInstance();
    } catch (ClassCastException e) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot initialize TLSConfigurer, %s does not implement TLSConfigurer.", impl),
          e);
    }

    configurer.initialize(properties);

    return configurer;

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Correct the fully-qualified class name in the configuration.
  2. Ensure the JAR containing the class is on the runtime classpath of the client process (driver and executors).
  3. Give the implementation a public no-argument constructor (it must implement TLSConfigurer).
  4. Run with the default TLSConfigurer by removing the property to isolate whether the class loading is the problem.

Example fix

// before: class missing or needs args
class MyTls implements TLSConfigurer {
  MyTls(String path) { ... }
}
// after: public no-arg constructor, correct FQCN in config
public class MyTls implements TLSConfigurer {
  public MyTls() {}
  public void initialize(Map<String, String> properties) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight check before configuring
Class<?> c = Class.forName(implClassName);
if (!TLSConfigurer.class.isAssignableFrom(c)) throw new IllegalArgumentException(implClassName);
if (c.getConstructor() == null) throw new IllegalArgumentException("no no-arg ctor: " + implClassName);

Try / catch

try {
  client = HTTPClient.builder(map).uri(baseUri).build();
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Cannot initialize TLSConfigurer implementation")) {
    // fall back to default TLS config and log the bad class name
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting rest.client.tls-implementation (or the equivalent TLS config) to a class name that is misspelled, absent from the classpath, or lacking a public no-argument constructor.

Common situations: Typo in the fully-qualified class name; the JAR containing the TLSConfigurer implementation is not on the Spark/Flink/worker classpath; the class requires constructor arguments; shaded/relocated class name used.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/1063aec2b312a2be. Report an issue: GitHub.