apache/beam · error · IllegalStateException
error when invoking Coder factory method
Error message
error when invoking Coder factory method
What it means
When a CoderProvider built by CoderProviders.fromStaticMethods is asked for a coder, it reflectively invokes the Coder class's static `of` factory method. If that invocation fails for any reflective reason (inaccessible, wrong arguments, the factory itself threw, class static-initializer failure, or a null result), coderFor wraps it in this IllegalStateException. It indicates the Coder class's factory method is broken or incompatible with the component coders supplied at runtime, not a problem with the pipeline code calling coderFor.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java:79
@Override
public <T> Coder<T> coderFor(TypeDescriptor<T> type, List<? extends Coder<?>> componentCoders)
throws CannotProvideCoderException {
if (!this.rawType.equals(type.getRawType())) {
throw new CannotProvideCoderException(
String.format(
"Unable to provide coder for %s, this factory can only provide coders for %s",
type, this.rawType));
}
try {
return (Coder<T>)
Preconditions.checkStateNotNull(
factoryMethod.invoke(this.rawType /* ignored */, componentCoders.toArray()));
} catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException
| NullPointerException
| ExceptionInInitializerError exn) {
throw new IllegalStateException(
"error when invoking Coder factory method " + factoryMethod, exn);
}
}
////////////////////////////////////////////////////////////////////////////////
// Type raw type used to filter the incoming type on.
private final Class<?> rawType;
// Method to create a coder given component coders
// For a Coder class of kind * -> * -> ... n times ... -> *
// this has type Coder<?> -> Coder<?> -> ... n times ... -> Coder<T>
private final Method factoryMethod;
/** Returns a CoderProvider that invokes the given static factory method to create the Coder. */
private CoderProviderFromStaticMethods(Class<?> rawType, Class<?> coderClazz) {
this.rawType = rawType;
this.factoryMethod = getFactoryMethod(coderClazz);View on GitHub (pinned to 12126d8942)
Solutions
- Read the cause (exn) in the stack trace — it is the real failure from the static `of` factory method; fix the exception thrown inside your Coder's `of` method
- Verify the `of` method returns a non-null Coder for all valid component-coder combinations
- Check that the number and types of component coders your pipeline supplies match the type parameters of the registered Coder class
- If the cause is ExceptionInInitializerError, fix the Coder class's static initializer (missing dependency, bad config)
- If the Coder cannot support arbitrary component coders, register it with CoderProviders.forCoder for a concrete TypeDescriptor instead of fromStaticMethods
Example fix
// before: custom coder factory throws on unexpected component coder
public static MyCoder of(Coder<String> c) {
if (!c.getClass().equals(StringUtf8Coder.class)) { throw new IllegalArgumentException(...); }
...
}
// after: handle any Coder<String> or throw CannotProvideCoderException path instead
public static MyCoder of(Coder<String> c) {
return new MyCoder(c); // accept any Coder<String>
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify the factory works before registering
Method of = coderClazz.getDeclaredMethod("of",
java.util.Arrays.stream(coderClazz.getTypeParameters())
.map(p -> Coder.class).toArray(Class[]::new));
of.setAccessible(true);
// smoke-test with placeholder coders where feasible; of.getReturnType() must be non-void Type guard
static boolean hasWorkingFactory(Class<?> coderClazz) {
try {
Class<?>[] args = new Class<?>[coderClazz.getTypeParameters().length];
java.util.Arrays.fill(args, Coder.class);
Method of = coderClazz.getDeclaredMethod("of", args);
return Modifier.isStatic(of.getModifiers())
&& coderClazz.isAssignableFrom(of.getReturnType()) && of.isAccessible();
} catch (ReflectiveOperationException | SecurityException e) { return false; }
} Try / catch
try {
Coder<T> coder = registry.getCoder(type, componentCoders);
} catch (IllegalStateException e) {
// inspect e.getCause() — the failure inside the Coder's static of() method
logger.error("Coder factory failed for " + type, e.getCause());
throw new CannotProvideCoderException("factory failure for " + type, e);
} Prevention
- Make the static of() method total: never throw or return null for valid component coders
- Avoid strict instanceof checks on component coders inside of(); useCoder consolidations instead
- Keep of()'s signature exactly one Coder parameter per type parameter
- Smoke-test coderFor() in unit tests before registering the provider in the CoderRegistry
- Read the cause chain of the IllegalStateException — it always carries the real exception from of()
When it happens
Trigger: Calling CoderProviders.fromStaticMethods(rawType, coderClazz) and then resolving a type through CoderRegistry when the registered Coder's static of(Coder<?>...) method throws an exception internally, returns null, or the component coders passed do not match what the factory expects (e.g. wrong arity or incompatible Coder<T> generic binding due to type erasure).
Common situations: A custom Coder's `of` method validates component coders and throws IllegalArgumentException (caught as InvocationTargetException); a Coder was refactored so its `of` no longer accepts the registered component coders; a static initializer of the Coder class fails (ExceptionInInitializerError) from bad config or missing classes; a user-written `of` returns null on an unexpected input.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- cannot register Coder : does not have an accessible method n
- cannot register Coder : method named 'of' with arguments of
- cannot register Coder : method named 'of' with arguments of
- cannot register Coder : method named 'of' with arguments of
- %s is not one of the common types.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f27db77f470bbed5.
Report an issue: GitHub.