apache/hadoop · error · IllegalArgumentException

Null protocol

Error message

Null protocol

What it means

RPC.getProtocolVersion(Class<?> protocol) resolves a protocol's version, first from its @ProtocolInfo annotation (if protocolVersion != -1), then from a public static long versionID field. A null protocol class has no version to read, so it fails fast with IllegalArgumentException('Null protocol'). It is a caller-side wiring bug — the protocol variable was never assigned, typically in proxy construction paths (ProtocolProxy, RpcEngine version checks).

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RPC.java:177

    if (protocol == null) {
      return null;
    }
    ProtocolInfo anno = protocol.getAnnotation(ProtocolInfo.class);
    return  (anno == null) ? protocol.getName() : anno.protocolName();
  }
  
  /**
   * Get the protocol version from protocol class.
   * If the protocol class has a ProtocolAnnotation,
   * then get the protocol version from the annotation;
   * otherwise get it from the versionID field of the protocol class.
   *
   * @param protocol input protocol.
   * @return ProtocolVersion.
   */
  static public long getProtocolVersion(Class<?> protocol) {
    if (protocol == null) {
      throw new IllegalArgumentException("Null protocol");
    }
    long version;
    ProtocolInfo anno = protocol.getAnnotation(ProtocolInfo.class);
    if (anno != null) {
      version = anno.protocolVersion();
      if (version != -1)
        return version;
    }
    try {
      Field versionField = protocol.getField("versionID");
      versionField.setAccessible(true);
      return versionField.getLong(protocol);
    } catch (NoSuchFieldException ex) {
      throw new RuntimeException(ex);
    } catch (IllegalAccessException ex) {
      throw new RuntimeException(ex);
    }
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Null-check the protocol class before building proxies and fail with a message naming the config/source of the class.
  2. Fix the upstream lookup: verify the protocol class name string, use Class.forName with error propagation instead of null-swallowing helpers.
  3. Ensure the class also carries @ProtocolInfo(protocolVersion=...) or a versionID field, or the next step will fail differently.

Example fix

// before
Class<?> proto = protocolClasses.get(conf.get("my.rpc.protocol")); // missing key -> null
long v = RPC.getProtocolVersion(proto); // IllegalArgumentException: Null protocol

// after
String name = Objects.requireNonNull(conf.get("my.rpc.protocol"), "my.rpc.protocol unset");
Class<?> proto;
try {
 proto = Class.forName(name);
} catch (ClassNotFoundException e) {
 throw new IllegalStateException("Bad my.rpc.protocol: " + name, e);
}
long v = RPC.getProtocolVersion(proto);
Defensive patterns

Strategy: validation

Validate before calling

java.util.Objects.requireNonNull(protocol,
    "protocol class must not be null when resolving its version");
// and ensure it is versioned
if (protocol.getAnnotation(ProtocolInfo.class) == null
    && !hasVersionIdField(protocol)) {
  throw new IllegalStateException(protocol + " needs @ProtocolInfo or versionID");
}

Type guard

static boolean isVersionedProtocol(Class<?> c) {
  if (c == null) return false;
  ProtocolInfo anno = c.getAnnotation(ProtocolInfo.class);
  if (anno != null && anno.protocolVersion() != -1) return true;
  try { c.getField("versionID"); return true; }
  catch (NoSuchFieldException e) { return false; }
}

Prevention

When it happens

Trigger: Calling RPC.getProtocolVersion(null); passing a null protocolClass into RPC.getProxy/waitForProxy paths that forward it here; configuration-driven protocol loading where the class name resolves to null (Class.forName wrapped so failures yield null); generics erasure returning null from a map of protocols.

Common situations: Custom RPC clients building proxies from config keys that are missing or misspelled; UGI/doAs wrappers losing the protocol argument; test code passing an unset field.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/af9dabf274948599. Report an issue: GitHub.