apache/beam · error · java.lang.IllegalArgumentException

Found multiple SchemaTransformProvider implementations with…

Error message

Found multiple SchemaTransformProvider implementations with the same identifier 

What it means

The expansion service discovers SchemaTransformProvider implementations via Java's ServiceLoader (META-INF/services). The private constructor of ExpansionServiceSchemaTransformProvider throws IllegalArgumentException if two providers on the classpath advertise the same identifier(). This prevents ambiguous dispatch of transform requests.

Solutions

  1. Run mvn dependency:tree (or gradle dependencies) to find duplicate jars providing the same SchemaTransformProvider identifier and exclude one
  2. Check META-INF/services/org.apache.beam.sdk.schemas.transforms.SchemaTransformProvider entries across all jars for the conflicting identifier
  3. Pin/upstream a single version of the provider library and rebuild the classpath
  4. If duplicates are intentional (different versions), use a classloader/shading configuration that isolates them

Example fix

// before (pom.xml)
<dependency><groupId>org.apache.beam</groupId><artifactId>beam-sdks-java-io-myio</artifactId></dependency>
<dependency><groupId>com.vendor</groupId><artifactId>myio-legacy</artifactId></dependency> // same identifier
// after
<dependency><groupId>com.vendor</groupId><artifactId>myio-legacy</artifactId><exclusions><exclusion><groupId>org.apache.beam</groupId><artifactId>beam-sdks-java-io-myio</artifactId></exclusion></exclusions></dependency>
Defensive patterns

Strategy: validation

Validate before calling

// Before building the service jar, check for duplicate registrations:
// unzip -p each jar META-INF/services/org.apache.beam.sdk.schemas.transforms.SchemaTransformProvider | sort | uniq -d

Try / catch

try { service = ExpansionService.create(args); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Found multiple SchemaTransformProvider")) { /* dedupe classpath */ } throw e; }

Prevention

When it happens

Trigger: Constructing the singleton ExpansionServiceSchemaTransformProvider (e.g., at expansion service startup) when the classpath contains two jars each registering a SchemaTransformProvider with an identical identifier in META-INF/services/org.apache.beam.sdk.schemas.transforms.SchemaTransformProvider.

Common situations: Two different versions of the same provider jar on the classpath (e.g., beam-sdks-java-io-google-ads-platform vs vendored copy); a fat jar bundling duplicate service registrations; classpath 'shade' duplicates from transitive dependencies.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c45f9e0683bf5a9c. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/ExpansionServiceSchemaTransformProvider.java:56

import org.apache.beam.vendor.grpc.v1p69p0.com.google.protobuf.InvalidProtocolBufferException;
import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.collect.ImmutableMap;
import org.checkerframework.checker.nullness.qual.Nullable;

@SuppressWarnings({"rawtypes"})
public class ExpansionServiceSchemaTransformProvider
    implements TransformProvider<PCollectionRowTuple, PCollectionRowTuple> {

  private Map<String, org.apache.beam.sdk.schemas.transforms.SchemaTransformProvider>
      schemaTransformProviders = new HashMap<>();
  private static @Nullable ExpansionServiceSchemaTransformProvider transformProvider = null;

  private ExpansionServiceSchemaTransformProvider() {
    try {
      for (org.apache.beam.sdk.schemas.transforms.SchemaTransformProvider schemaTransformProvider :
          ServiceLoader.load(
              org.apache.beam.sdk.schemas.transforms.SchemaTransformProvider.class)) {
        if (schemaTransformProviders.containsKey(schemaTransformProvider.identifier())) {
          throw new IllegalArgumentException(
              "Found multiple SchemaTransformProvider implementations with the same identifier "
                  + schemaTransformProvider.identifier());
        }
        schemaTransformProviders.put(schemaTransformProvider.identifier(), schemaTransformProvider);
      }
    } catch (Exception e) {
      throw new RuntimeException(e.getMessage());
    }
  }

  public static ExpansionServiceSchemaTransformProvider of() {
    if (transformProvider == null) {
      transformProvider = new ExpansionServiceSchemaTransformProvider();
    }

    return transformProvider;
  }

View on GitHub (pinned to 12126d8942)