grpc/grpc-java · error · IllegalArgumentException

(message of wrapped InvalidProtocolBufferException)

Error message

(message of wrapped InvalidProtocolBufferException)

What it means

ProtoLiteUtils' MethodDescriptor Marshaller.parseBytes parses protobuf messages from bytes using the lite runtime with a global extension registry. When the lite parser throws InvalidProtocolBufferException (malformed wire format, unknown fields that cannot be skipped, or missing required extensions), it is rethrown as an IllegalArgumentException wrapping the original exception — so the informative message lives in the cause.

Source

Thrown at protobuf-lite/src/main/java/io/grpc/protobuf/lite/ProtoLiteUtils.java:275

    private final T defaultInstance;

    MetadataMarshaller(T defaultInstance) {
      this.defaultInstance = defaultInstance;
    }

    @Override
    public byte[] toBytes(T value) {
      return value.toByteArray();
    }

    @Override
    @SuppressWarnings("unchecked")
    public T parseBytes(byte[] serialized) {
      try {
        return (T) defaultInstance.getParserForType().parseFrom(serialized, globalRegistry);
      } catch (InvalidProtocolBufferException ipbe) {
        throw new IllegalArgumentException(ipbe);
      }
    }
  }
}

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Inspect the cause chain (IllegalArgumentException#getCause) to see the real InvalidProtocolBufferException message identifying the wire-format problem.
  2. Confirm client and server generated code come from the same .proto version and both use protobuf-lite consistently.
  3. Verify the RPC method is invoked with the correct request/response message types matching the service definition.
  4. Check for version skew: redeploy both ends with matching grpc-protobuf-lite and generated stub versions.

Example fix

// before
Foo foo = stub.getFoo(request); // fails with opaque IllegalArgumentException
// after
try {
  Foo foo = stub.getFoo(request);
} catch (IllegalArgumentException e) {
  log.error("protobuf parse failed", e.getCause()); // InvalidProtocolBufferException details
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  T msg = marshaller.parseBytes(serialized);
} catch (IllegalArgumentException e) {
  Throwable cause = e.getCause(); // InvalidProtocolBufferException with the real reason
  throw new Status.INTERNAL.withCause(cause).withDescription("bad protobuf").asRuntimeException();
}

Prevention

When it happens

Trigger: Any gRPC call using protobuf-lite marshalling where the received message bytes fail protobuf parsing: wrong message type on a method, corrupted/truncated frame, sender using proto2 required fields not set, or a serializer/deserializer version mismatch.

Common situations: Client and server disagree on the RPC message type for a method, mixing protobuf-lite and full protobuf with incompatible generated code, network middleboxes corrupting payloads, or deserializing a response from a service that changed its schema.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/d0b3bc7f4ea218cd. Report an issue: GitHub.