apache/seatunnel · error · FactoryException

Could not load service provider for factories.

Error message

Could not load service provider for factories.

What it means

FactoryUtil.discoverFactories throws this FactoryException when the JDK ServiceLoader fails with a ServiceConfigurationError while iterating Factory providers — i.e. a class named in an SPI service file cannot be loaded or instantiated (missing class, NoClassDefFoundError, constructor failure).

Source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java:409

    }

    @SuppressWarnings("unchecked")
    public static <T extends Factory> List<T> discoverFactories(
            ClassLoader classLoader, Class<T> factoryClass) {
        return discoverFactories(classLoader).stream()
                .filter(f -> factoryClass.isAssignableFrom(f.getClass()))
                .map(f -> (T) f)
                .collect(Collectors.toList());
    }

    public static List<Factory> discoverFactories(ClassLoader classLoader) {
        try {
            final List<Factory> result = new LinkedList<>();
            ServiceLoader.load(Factory.class, classLoader).iterator().forEachRemaining(result::add);
            return result;
        } catch (ServiceConfigurationError e) {
            LOG.error("Could not load service provider for factories.", e);
            throw new FactoryException("Could not load service provider for factories.", e);
        }
    }

    /**
     * This method is called by SeaTunnel Web to get the full option rule of a source.
     *
     * @return Option rule
     */
    public static OptionRule sourceFullOptionRule(@NonNull TableSourceFactory factory) {
        OptionRule sourceOptionRule = factory.optionRule();
        if (sourceOptionRule == null) {
            throw new FactoryException("sourceOptionRule can not be null");
        }

        Class<? extends SeaTunnelSource> sourceClass = factory.getSourceClass();
        if (factory instanceof SupportParallelism
                // TODO: Implement SupportParallelism in the TableSourceFactory instead of the
                // SeaTunnelSource

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read the LOG.error stack trace to identify which provider class failed and why.
  2. Fix the missing/conflicting dependency for that connector jar (often shading or version conflict).
  3. Remove or repair the corrupted connector jar from the plugins directory.
  4. Verify the provider class has a public no-arg constructor and implements Factory.

Example fix

// before: jar missing shade-relocated guava -> ServiceConfigurationError
// after: rebuild connector with dependency relocation or add the missing jar to the classpath
Defensive patterns

Strategy: try-catch

Validate before calling

try (var urls = ServiceLoader.load(Factory.class, classLoader)) {
    urls.iterator().forEachRemaining(f -> {}); // dry-run to surface ServiceConfigurationError early
}

Try / catch

try {
    factories = FactoryUtil.discoverFactories(classLoader);
} catch (FactoryException e) {
    if (e.getCause() instanceof ServiceConfigurationError) {
        LOG.error("Broken SPI provider jar: {}", e.getCause().getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: ServiceLoader.load(Factory.class, classLoader) iteration throws ServiceConfigurationError because a provider class listed in META-INF/services is missing, has an incompatible dependency version, or fails in its static initializer.

Common situations: Connector jar with a missing transitive dependency; shaded jar missing/relocating classes the SPI references; JVM module/classloader visibility issues; corrupted jar in the plugins directory.

Related errors


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