We pass `null` for the class name here:

https://github.com/elastic/elasticsearch/blob/f086dd18ddc705bf84a1ff99d35196ec2498fd52/server/src/main/java/org/elasticsearch/plugins/PluginDescriptor.java#L261

However the class name is mandatory for the transport protocol today:

https://github.com/elastic/elasticsearch/blob/f086dd18ddc705bf84a1ff99d35196ec2498fd52/server/src/main/java/org/elasticsearch/plugins/PluginDescriptor.java#L156

This prevents various APIs from working in a cluster with stable plugins installed.
x-pack/plugin/security/src/test/java/org/elasticsearch/test/SecurityIntegTestCase.java
public static void destroyDefaultSettings() {
        SECURITY_DEFAULT_SETTINGS = null;
        customSecuritySettingsSource = null;
    }
    @Rule
    
    public ExternalResource externalResource = new ExternalResource() {
        @Override
        protected void before() throws Throwable {
            Scope currentClusterScope = getCurrentClusterScope();
            switch (currentClusterScope) {
                case SUITE:
                    if (customSecuritySettingsSource == null) {
                        customSecuritySettingsSource = new CustomSecuritySettingsSource(
                            transportSSLEnabled(),
                            createTempDir(),
                            currentClusterScope
                        );
                    }
                    break;
                case TEST:
                    customSecuritySettingsSource = new CustomSecuritySettingsSource(
                        transportSSLEnabled(),
                        createTempDir(),
                        currentClusterScope
                    );
                    break;
            }
        }
    };