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.
server/src/main/java/org/elasticsearch/plugins/PluginDescriptor.java
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * An in-memory representation of the plugin descriptor.
 */
public class PluginDescriptor implements Writeable, ToXContentObject {
    public static final String INTERNAL_DESCRIPTOR_FILENAME = "plugin-descriptor.properties";
    public static final String STABLE_DESCRIPTOR_FILENAME = "stable-plugin-descriptor.properties";
    public static final String NAMED_COMPONENTS_FILENAME = "named_components.json";
    public static final String ES_PLUGIN_POLICY = "plugin-security.policy";
    private static final TransportVersion LICENSED_PLUGINS_SUPPORT = TransportVersions.V_7_11_0;
    private static final TransportVersion MODULE_NAME_SUPPORT = TransportVersions.V_8_3_0;
    private static final TransportVersion BOOTSTRAP_SUPPORT_REMOVED = TransportVersions.V_8_4_0;
    private final String name;
    private final String description;
    private final String version;
    private final Version elasticsearchVersion;
    private final String javaVersion;
    private final String classname;
    private final String moduleName;
    private final List<String> extendedPlugins;
    private final boolean hasNativeController;
    private final boolean isLicensed;