apache/hadoop · error · ServiceException

Too many or few parameters for request. Method: [{}], Expect

Error message

Too many or few parameters for request. Method: [{}], Expected: 2, Actual: {}

What it means

ProtobufRpcEngine's InvocationHandler (the layer under a java.lang.reflect proxy created by RPC.getProxy for protobuf protocols) insists every protocol method has exactly two arguments: an RpcController plus one request Message. If args.length != 2 it throws ServiceException immediately, before any network I/O. Hitting it almost always means a non-standard method was invoked through the protobuf proxy.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/ProtobufRpcEngine.java:221

     * <li>Exceptions from the server are wrapped in RemoteException and are
     * set as cause in ServiceException</li>
     * </ol>
     * 
     * Note that the client calling protobuf RPC methods, must handle
     * ServiceException by getting the cause from the ServiceException. If the
     * cause is RemoteException, then unwrap it to get the exception thrown by
     * the server.
     */
    @Override
    public Message invoke(Object proxy, final Method method, Object[] args)
        throws ServiceException {
      long startTime = 0;
      if (LOG.isDebugEnabled()) {
        startTime = Time.monotonicNow();
      }
      
      if (args.length != 2) { // RpcController + Message
        throw new ServiceException(
            "Too many or few parameters for request. Method: ["
            + method.getName() + "]" + ", Expected: 2, Actual: "
            + args.length);
      }
      if (args[1] == null) {
        throw new ServiceException("null param while calling Method: ["
            + method.getName() + "]");
      }

      // if Tracing is on then start a new span for this rpc.
      // guard it in the if statement to make sure there isn't
      // any extra string manipulation.
      Tracer tracer = Tracer.curThreadTracer();
      TraceScope traceScope = null;
      if (tracer != null) {
        traceScope = tracer.newScope(RpcClientUtil.methodToTraceString(method));
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Keep the protobuf protocol interface to exactly (RpcController, RequestMessage) methods; put helper/extra-arity methods in a separate interface or the client-side translator class.
  2. Invoke utility methods on the translator (e.g., ClientNamenodeProtocolTranslatorPB), not on the raw PB proxy.
  3. If you must call via reflection, assert the 2-arg shape first.

Example fix

// before
public interface MyProtocolPB {
  RpcController getController();                       // 0 args -> ServiceException
  MyResponseProto execute(RpcController c, MyRequestProto req);
}
MyProtocolPB proxy = RPC.getProxy(MyProtocolPB.class, version, addr, conf);
proxy.getController();

// after
public interface MyProtocolPB { // wire interface stays 2-arg only
  MyResponseProto execute(RpcController c, MyRequestProto req);
}
public class MyProtocolTranslatorPB { // helpers live here
  private final MyProtocolPB proxy;
  RpcController getController() { return null; }
 MyResponseProto execute(MyRequestProto req) { return proxy.execute(null, req); }
}
Defensive patterns

Strategy: validation

Validate before calling

for (Method m : protoInterface.getMethods()) {
  if (!(m.getParameterCount() == 2
        && RpcController.class.isAssignableFrom(m.getParameterTypes()[0])
        && Message.class.isAssignableFrom(m.getParameterTypes()[1]))) {
    throw new IllegalStateException("Non-RPC method on PB interface: " + m);
  }
}

Type guard

static boolean isProtobufRpcMethod(Method m) {
  Class<?>[] p = m.getParameterTypes();
  return p.length == 2
      && RpcController.class.isAssignableFrom(p[0])
      && Message.class.isAssignableFrom(p[1])
      && Message.class.isAssignableFrom(m.getReturnType());
}

Prevention

When it happens

Trigger: Calling a default or static helper method that was added to the protocol interface with a different arity through the RPC proxy; invoking a translator-style method (extra arg) directly on the proxy object; reflective tooling (Mockito, AOP wrappers) calling proxy methods with modified argument arrays.

Common situations: Extending a *Protocol interface with convenience methods and calling them via the PB proxy instead of the translator; hand-rolled reflection over Hadoop proxies; version skew where a newer interface adds non-RPC methods.

Related errors


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