{"record":{"id":"92960305ee2b8a32","repo":"apache/cassandra","slug":"sstable-format-name-for-s-must-be-non-empty-lowe","errorCode":null,"errorMessage":"SSTable format name for %s must be non-empty, lower-case letters only string","messagePattern":"SSTable format name for (.+?) must be non-empty, lower-case letters only string","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/config/DatabaseDescriptor.java","lineNumber":1934,"sourceCode":"                with = \"encryption\";\n            throw new ConfigurationException(\"commitlog_disk_access_mode = \" + accessModeDirectIoPair.left + \" is not supported with \" + with + \". Please use 'auto' when unsure.\", false);\n        }\n        else if (!compressOrEncrypt && accessModeDirectIoPair.left != DiskAccessMode.mmap && accessModeDirectIoPair.left != DiskAccessMode.direct)\n        {\n            throw new ConfigurationException(\"commitlog_disk_access_mode = \" + accessModeDirectIoPair.left + \" is not supported. Please use 'auto' when unsure.\", false);\n        }\n    }\n\n    private static void validateSSTableFormatFactories(Iterable<SSTableFormat.Factory> factories)\n    {\n        Map<String, SSTableFormat.Factory> factoryByName = new HashMap<>();\n        for (SSTableFormat.Factory factory : factories)\n        {\n            if (factory.name() == null)\n                throw new ConfigurationException(String.format(\"SSTable format name in %s cannot be null\", factory.getClass().getCanonicalName()));\n\n            if (!factory.name().matches(\"^[a-z]+$\"))\n                throw new ConfigurationException(String.format(\"SSTable format name for %s must be non-empty, lower-case letters only string\", factory.getClass().getCanonicalName()));\n\n            SSTableFormat.Factory prev = factoryByName.put(factory.name(), factory);\n            if (prev != null)\n                throw new ConfigurationException(String.format(\"Multiple sstable format implementations with the same name %s: %s and %s\", factory.name(), factory.getClass().getCanonicalName(), prev.getClass().getCanonicalName()));\n        }\n    }\n\n    private static ImmutableMap<String, Supplier<SSTableFormat<?, ?>>> validateAndMatchSSTableFormatOptions(Iterable<SSTableFormat.Factory> factories, Map<String, Map<String, String>> options)\n    {\n        ImmutableMap.Builder<String, Supplier<SSTableFormat<?, ?>>> providersBuilder = ImmutableMap.builder();\n        if (options == null)\n            options = ImmutableMap.of();\n        for (SSTableFormat.Factory factory : factories)\n        {\n            Map<String, String> formatOptions = options.getOrDefault(factory.name(), ImmutableMap.of());\n            providersBuilder.put(factory.name(), () -> factory.getInstance(ImmutableMap.copyOf(formatOptions)));\n        }\n        ImmutableMap<String, Supplier<SSTableFormat<?, ?>>> providers = providersBuilder.build();","sourceCodeStart":1916,"sourceCodeEnd":1952,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/DatabaseDescriptor.java#L1916-L1952","documentation":"SSTable format names become directory suffixes and config keys, so validateSSTableFormatFactories enforces they are non-empty, all-lowercase-letter strings matching ^[a-z]+$. A factory whose name() returns anything else (digits, underscores, uppercase, empty) is rejected with this ConfigurationException.","triggerScenarios":"A custom SSTableFormat.Factory returns a name that fails matches(\"^[a-z]+$\") — e.g. \"MyFormat\", \"my_format\", \"format2\", or \"\"; thrown during format factory registration at startup.","commonSituations":"Third-party format jars written before this validation existed; authors naming formats with underscores or version suffixes; copy-pasted factory code with a placeholder name.","solutions":["Change the factory's name() to return only lowercase letters, e.g. \"myformat\" instead of \"MyFormat\" or \"my_format\"","Remove or replace the offending third-party format factory jar if you don't need the format","Rename directories/data references accordingly — the format name is used in file suffixes, so pick the name before creating data"],"exampleFix":"// before\npublic String name() { return \"My_Format2\"; }\n// after\npublic String name() { return \"myformat\"; }","handlingStrategy":"validation","validationCode":"if (!String.valueOf(yaml.getOrDefault(\"partitioner\",\"\")).matches(\"^[a-zA-Z0-9_.$]+$\")) throw new IllegalStateException(\"bad partitioner name\");","typeGuard":null,"tryCatchPattern":"try { DatabaseDescriptor.daemonInitialization(); } catch (ConfigurationException e) { /* fix class name */ }","preventionTips":["Use fully-qualified class names in config"],"tags":["sstable","configuration","plugin","naming"],"backgroundTag":"invalid-identifier-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}