{"record":{"id":"5c7b155a349861fd","repo":"apache/cassandra","slug":"icompressor-serializedas-of-a-compressor-created","errorCode":null,"errorMessage":"ICompressor.serializedAs() of a compressor created by provider %s returned %s. It must return a non-anonymous built-in compressor class in package org.apache.cassandra.io.compress.","messagePattern":"ICompressor\\.serializedAs\\(\\) of a compressor created by provider (.+?) returned (.+?)\\. It must return a non-anonymous built-in compressor class in package org\\.apache\\.cassandra\\.io\\.compress\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/compress/CompressorRegistry.java","lineNumber":183,"sourceCode":"            if (provider == DEFAULT_COMPRESSION_PROVIDER)\n                throw t;\n\n            logger.warn(\"Failed to create compressor {}. Will attempt fallback to default if enabled. Message: {}\",\n                        compressorClass.getName(),\n                        t.getMessage());\n\n            if (provider.isFailOnMissingProvider())\n                throw t;\n\n            compressor = DEFAULT_COMPRESSION_PROVIDER.createCompressor(compressorClass, compressionOptions);\n        }\n\n        // Validate the masquerade target for both the provider and the fallback path: whatever is\n        // returned must serialize as exactly the compressor class that was requested, otherwise the\n        // schema / on-disk format would record a name that cannot be resolved on peers and restarts.\n        Class<? extends ICompressor> serializedAs = compressor.serializedAs();\n        if (serializedAs == null || serializedAs.getSimpleName().isEmpty())\n            throw new ConfigurationException(String.format(\"ICompressor.serializedAs() of a compressor created by provider %s returned %s. \" +\n                                                           \"It must return a non-anonymous built-in compressor class in package \" +\n                                                           \"org.apache.cassandra.io.compress.\",\n                                                           provider.getClass(),\n                                                           serializedAs));\n        if (serializedAs != compressorClass)\n            throw new ConfigurationException(String.format(\"The result of ICompressor.serializedAs(), %s, of a compressor object created \" +\n                                                           \"by a compressor provider %s does not match the compressor class to get a compressor for. \" +\n                                                           \"You need to override serializedAs() method of your custom compressor and return \" +\n                                                           \"base compressor class it is the substitute for.\",\n                                                           serializedAs,\n                                                           provider.getClass()));\n        return compressor;\n    }\n\n    /**\n     * Populates the registry with compression providers specified in the configuration.\n     * Should be called once during initialization to ensure providers are registered and available\n     * for use. If a provider fails to initialize and fallback is enabled, the default provider is used.","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/compress/CompressorRegistry.java#L165-L201","documentation":"CompressorRegistry.getCompressor() resolves a compressor via a registered provider, then validates that ICompressor.serializedAs() returns a real class equal to the requested built-in compressor class. If it returns null, an empty/anonymous class name, a class outside org.apache.cassandra.io.compress, or a different class than requested, a ConfigurationException is thrown because the on-disk format would record a compressor name peers could never resolve.","triggerScenarios":"Registering a custom ICompressorProvider whose created compressor's serializedAs() returns null, an empty-named or anonymous class, a class not in the org.apache.cassandra.io.compress package, or a class differing from the one requested (masquerade failure).","commonSituations":"Custom compressor plugins implemented as anonymous or wrapper classes; providers returning repackaged compressors whose serializedAs points at the wrapper; typos in the registered class mapping; plugin version drift after upgrade.","solutions":["Make the provider return a compressor whose serializedAs() is the exact built-in class requested (e.g. LZ4Compressor.class) in package org.apache.cassandra.io.compress","Fix anonymous/wrapper compressors to delegate serializedAs() to the underlying built-in compressor","Unregister/fix the offending provider and reconfigure the table to a built-in compressor class","Add a startup self-check that calls getCompressor() for each configured compression class and fails fast"],"exampleFix":"// before\npublic Class<? extends ICompressor> serializedAs() { return this.getClass(); } // anonymous wrapper\n// after\npublic Class<? extends ICompressor> serializedAs() { return LZ4Compressor.class; } // exact built-in target","handlingStrategy":"validation","validationCode":"// Java: pre-validate a provider's compressor before registering\nClass<? extends ICompressor> sa = compressor.serializedAs();\nif (sa == null || sa.getName().startsWith(\"org.apache.cassandra.io.compress.$\")\n    || !sa.getName().startsWith(\"org.apache.cassandra.io.compress.\"))\n    throw new ConfigurationException(\"Provider compressor serializes as non-builtin: \" + sa);","typeGuard":"static boolean isMasqueradeSafe(ICompressor c, Class<? extends ICompressor> requested) {\n    Class<? extends ICompressor> sa = c.serializedAs();\n    return sa != null && !sa.getSimpleName().isEmpty() && sa == requested;\n}","tryCatchPattern":"try { ICompressor c = CompressorRegistry.instance.getCompressor(LZ4Compressor.class, provider); }\ncatch (ConfigurationException e) { logger.error(\"Invalid compressor provider\", e); useDefaultCompressor(); }","preventionTips":["Return built-in classes from serializedAs(), never anonymous/wrapper classes","Add unit tests asserting serializedAs() equals the requested class","Keep custom provider plugins in sync with registry expectations","Fail fast at startup by resolving all configured compressors once"],"tags":["compression","registry","configuration","plugin"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}