apache/pulsar · error · RuntimeException

Invalid object type '%s' when expecting '%s'

Error message

Invalid object type '%s' when expecting '%s'

What it means

TypeCheckUtil.checkType performs a runtime instanceof check and, when the supplied object is not an instance of the expected class, throws a RuntimeException with 'Invalid object type X when expecting Y'. Pulsar uses it internally where schema/object types must line up (e.g. typed message builders or schema validation paths). The exception is unchecked and carries the actual vs. expected fully-qualified class names.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/util/TypeCheckUtil.java:28

 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.pulsar.client.util;

import lombok.experimental.UtilityClass;

@UtilityClass
public class TypeCheckUtil {
    @SuppressWarnings("unchecked")
    public static <T> T checkType(Object o, Class<T> clazz) {
        if (!clazz.isInstance(o)) {
            throw new RuntimeException(
                    String.format("Invalid object type '%s' when expecting '%s'",
                            o.getClass().getName(), clazz.getName()));
        }
        return (T) o;
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Make the object you pass match the class the schema was built with (check Schema.of(...) / JSONSchema.of(Class) generic parameter).
  2. Verify producer and consumer use the same message POJO/version — recompile against the updated schema class.
  3. If types legitimately differ, convert/map the object to the expected type before the call.
  4. Use a typed schema (Schema.AVRO(Foo.class)) instead of a generic one so generics catch mismatches at compile time.

Example fix

// before
Schema<String> schema = Schema.STRING;
producer.newMessage(schema).value(42).send(); // Invalid object type 'java.lang.Integer' when expecting 'java.lang.String'
// after
producer.newMessage(schema).value("42").send();
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(expectedClass.isInstance(value))) {
    throw new IllegalArgumentException("Expected " + expectedClass.getName() + " but got "
        + (value == null ? "null" : value.getClass().getName()));
}

Type guard

static <T> boolean isExpectedType(Object o, Class<T> clazz) {
    return clazz.isInstance(o);
}
// usage: if (isExpectedType(obj, Foo.class)) { Foo foo = clazz.cast(obj); }

Try / catch

try {
    producer.newMessage(schema).value(obj).send();
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid object type")) {
        throw new IllegalArgumentException("Message value does not match schema type", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing an object of the wrong Java type to a Pulsar API that internally calls TypeCheckUtil.checkType — e.g. supplying a value/message/schema object whose runtime class differs from the schema's expected class (Schema<Foo> but a Bar instance, or a generic JSON object where a POJO is expected).

Common situations: Schema/POJO mismatches after changing the message class (version drift between producer and consumer code); using Schema.AUTO/JSON with raw Maps or byte arrays instead of the typed class; generics erasure hiding the mismatch at compile time.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/18259354dae685c8. Report an issue: GitHub.