{"record":{"id":"42bac5d6348edcdc","repo":"apache/flink","slug":"multiple-compatible-client-factories-found-for","errorCode":null,"errorMessage":"Multiple compatible client factories found for:\n{}.","messagePattern":"Multiple compatible client factories found for:\n(.+?)\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"flink-clients/src/main/java/org/apache/flink/client/deployment/DefaultClusterClientServiceLoader.java","lineNumber":83,"sourceCode":"                    compatibleFactories.add(factory);\n                }\n            } catch (Throwable e) {\n                if (e instanceof NoClassDefFoundError\n                        || e.getCause() instanceof NoClassDefFoundError) {\n                    LOG.info(\"Could not load factory due to missing dependencies.\");\n                } else {\n                    throw e;\n                }\n            }\n        }\n\n        if (compatibleFactories.size() > 1) {\n            final List<String> configStr =\n                    configuration.toMap().entrySet().stream()\n                            .map(e -> e.getKey() + \"=\" + e.getValue())\n                            .collect(Collectors.toList());\n\n            throw new IllegalStateException(\n                    \"Multiple compatible client factories found for:\\n\"\n                            + String.join(\"\\n\", configStr)\n                            + \".\");\n        }\n\n        if (compatibleFactories.isEmpty()) {\n            throw new IllegalStateException(\n                    \"No ClusterClientFactory found. If you were targeting a Yarn cluster, \"\n                            + \"please make sure to export the HADOOP_CLASSPATH environment variable or have hadoop in your \"\n                            + \"classpath. For more information refer to the \\\"Deployment\\\" section of the official \"\n                            + \"Apache Flink documentation.\");\n        }\n\n        return (ClusterClientFactory<ClusterID>) compatibleFactories.get(0);\n    }\n\n    @Override\n    public Stream<String> getApplicationModeTargetNames() {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-clients/src/main/java/org/apache/flink/client/deployment/DefaultClusterClientServiceLoader.java#L65-L101","documentation":"Thrown by DefaultClusterClientServiceLoader.getClusterClientFactory when more than one ClusterClientFactory implementation reports isCompatible(configuration) as true. Flink discovers all factories via Java ServiceLoader and checks each one; if multiple match (e.g., both a YARN and Kubernetes factory consider the config compatible), it cannot unambiguously select one and aborts. The error includes the full configuration map for debugging.","triggerScenarios":"Setting configuration keys that make the config simultaneously compatible with multiple deployment backends (e.g., having both YARN and Kubernetes related settings); having multiple factory JARs on the classpath that overlap in their isCompatible logic; a misconfigured or duplicate SPI registration.","commonSituations":"Custom factory implementations with overly broad isCompatible checks; classpath pollution from multiple Flink connector distributions; experimental or custom deployment plugins that conflict with built-in factories.","solutions":["Set execution.target explicitly to disambiguate the deployment backend","Remove conflicting connector JARs from the classpath (only include the one deployment backend you intend to use)","Review the configuration map printed in the error message to identify overlapping keys"],"exampleFix":"// before (ambiguous config)\nconfig.set(\"execution.target\", \"yarn\");\nconfig.set(\"kubernetes.cluster-id\", \"my-cluster\");  // confuses K8s factory\n\n// after\nconfig.set(\"execution.target\", \"yarn\");\n// remove Kubernetes-specific keys","handlingStrategy":"validation","validationCode":"// Before calling getClusterClientFactory, verify config targets one backend:\nString target = configuration.get(DeploymentOptions.TARGET);\nif (target == null || target.isBlank()) {\n    throw new IllegalArgumentException(\n        \"Set execution.target to disambiguate the deployment backend.\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ClusterClientFactory<?> factory = serviceLoader.getClusterClientFactory(config);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Multiple compatible\")) {\n        System.err.println(\"Multiple factories matched. Set execution.target explicitly.\");\n    }\n    throw e;\n}","preventionTips":["Always set execution.target to a single, explicit value","Remove connector JARs for deployment backends you don't use from the classpath","Audit the full config map (printed in the error) for keys that match multiple backends"],"tags":["deployment","service-loader","configuration","classpath"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}