{"record":{"id":"a53f6e4b690387a5","repo":"apache/cassandra","slug":"unable-to-get-startup-checks-via-serviceloader-cu","errorCode":null,"errorMessage":"Unable to get startup checks via ServiceLoader. Custom checks will not be triggered.","messagePattern":"Unable to get startup checks via ServiceLoader\\. Custom checks will not be triggered\\.","errorType":"exception","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/StartupChecks.java","lineNumber":182,"sourceCode":"    public StartupChecks withServiceLoaderTests()\n    {\n        Set<StartupCheck> customChecks = new HashSet<>();\n        Set<String> uniqueNames = new HashSet<>();\n        Set<String> duplicitNames = new HashSet<>();\n\n        try\n        {\n            for (StartupCheck check : ServiceLoader.load(StartupCheck.class))\n            {\n                if (!uniqueNames.add(check.name()))\n                    duplicitNames.add(check.name());\n                else\n                    customChecks.add(check);\n            }\n        }\n        catch (ServiceConfigurationError t)\n        {\n            throw new ConfigurationException(\"Unable to get startup checks via ServiceLoader. \" +\n                                             \"Custom checks will not be triggered.\", t);\n        }\n\n        if (!duplicitNames.isEmpty())\n        {\n            throw new IllegalStateException(\"There was an attempt to load custom startup \" +\n                                            \"checks with same name which is ambiguous: \" + duplicitNames);\n        }\n\n        for (StartupCheck customCheck : customChecks)\n        {\n            for (StartupCheck preFlightCheck : preFlightChecks)\n            {\n                if (preFlightCheck.name().equals(customCheck.name()))\n                {\n                    throw new IllegalStateException(\"There was an attempt to load custom startup check \" +\n                                                    \"with same name as in-built check: \" + preFlightCheck.name());\n                }","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StartupChecks.java#L164-L200","documentation":"Cassandra discovers custom StartupCheck implementations via the Java ServiceLoader mechanism (META-INF/services entries). If the ServiceLoader iteration throws a ServiceConfigurationError while enumerating providers, Cassandra wraps it in a ConfigurationException so startup aborts with a clear message explaining that custom checks were not loaded.","triggerScenarios":"A META-INF/services/org.apache.cassandra.service.StartupCheck file references a class that cannot be loaded or instantiated (missing class, constructor throwing, malformed provider file, wrong class name) so ServiceIterator.next throws ServiceConfigurationError during getCustomStartupChecks.","commonSituations":"Typos in the provider-configuration file, custom check jar missing from the classpath after an upgrade, provider class compiled against a different Cassandra version (NoSuchMethodError/NoClassDefFoundError), a provider constructor that throws.","solutions":["Fix the class listed in META-INF/services/org.apache.cassandra.service.StartupCheck: ensure it exists on the classpath and has a public no-arg constructor","Read the cause (ConfigurationException is chained to the ServiceConfigurationError) to identify the exact load failure","Remove or correct the stale provider entry if the custom check is no longer needed","Verify the custom check jar is compatible with the running Cassandra version"],"exampleFix":"// before (META-INF/services/org.apache.cassandra.service.StartupCheck)\ncom.example.MyCheck\n// class not on classpath -> ServiceConfigurationError\n// after: ship the jar containing com.example.MyCheck in lib/ and keep the entry, or delete the line","handlingStrategy":"validation","validationCode":"for each META-INF/services entry, Class.forName(name) in a pre-flight script; fail deploy if ClassNotFoundException or no public no-arg constructor","typeGuard":null,"tryCatchPattern":"try { getCustomStartupChecks(); } catch (ConfigurationException e) { logger.error(\"Custom startup check failed to load\", e.getCause()); throw e; }","preventionTips":["Keep META-INF/services entries in sync with shipped jars","Smoke-test custom checks in CI against the target Cassandra version","Never let provider constructors do work that can throw"],"tags":["serviceloader","startup","configuration"],"backgroundTag":"module-init-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}