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/TransportVersions.java
TransportVersion version;
                try {
                    version = (TransportVersion) declaredField.get(null);
                } catch (IllegalAccessException e) {
                    throw new AssertionError(e);
                }
                builder.put(version.id(), version);
                if (Assertions.ENABLED) {
                    // 
                    var sameVersionNumber = versionIdFields.put(version.id(), fieldName);
                    assert sameVersionNumber == null
                        : "Versions ["
                            + sameVersionNumber
                            + "] and ["
                            + fieldName
                            + "] have the same version number ["
                            + version.id()
                            + "]. Each TransportVersion should have a different version number";
                }
            }
        }
        return Collections.unmodifiableNavigableMap(builder);
    }
    static Collection<TransportVersion> getAllVersions() {
        return VERSION_IDS.values();
    }
    // 
    private TransportVersions() {}
}