apache/beam · error · IllegalArgumentException
cannot register Coder : does not have an accessible method n
Error message
cannot register Coder : does not have an accessible method named 'of' with arguments of Coder type
What it means
CoderProviders.fromStaticMethods requires the Coder class to declare a method named exactly `of` whose parameter count equals the class's type-parameter count and whose parameters are all of type Coder. getDeclaredMethod throws NoSuchMethodException (or SecurityException blocks lookup) when no such method exists, and this IllegalArgumentException is thrown at registration time. Registration fails immediately; the provider is never usable.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java:115
this.factoryMethod = getFactoryMethod(coderClazz);
}
/**
* Returns the static {@code of} constructor method on {@code coderClazz} if it exists. It is
* assumed to have one {@link Coder} parameter for each type parameter of {@code coderClazz}.
*/
private static Method getFactoryMethod(Class<?> coderClazz) {
Method factoryMethodCandidate;
// Find the static factory method of coderClazz named 'of' with
// the appropriate number of type parameters.
int numTypeParameters = coderClazz.getTypeParameters().length;
Class<?>[] factoryMethodArgTypes = new Class<?>[numTypeParameters];
Arrays.fill(factoryMethodArgTypes, Coder.class);
try {
factoryMethodCandidate = coderClazz.getDeclaredMethod("of", factoryMethodArgTypes);
} catch (NoSuchMethodException | SecurityException exn) {
throw new IllegalArgumentException(
"cannot register Coder "
+ coderClazz
+ ": "
+ "does not have an accessible method named 'of' with "
+ numTypeParameters
+ " arguments of Coder type",
exn);
}
if (!Modifier.isStatic(factoryMethodCandidate.getModifiers())) {
throw new IllegalArgumentException(
"cannot register Coder "
+ coderClazz
+ ": "
+ "method named 'of' with "
+ numTypeParameters
+ " arguments of Coder type is not static");
}
if (!coderClazz.isAssignableFrom(factoryMethodCandidate.getReturnType())) {View on GitHub (pinned to 12126d8942)
Solutions
- Add or rename a static factory in the Coder class: `public static <T> MyCoder<T> of(Coder<T> componentCoder)` with one Coder parameter per type parameter of the class
- If the class's `of` signature cannot match, register the coder via CoderProviders.forCoder(typeDescriptor, coderInstance) instead of fromStaticMethods
- Ensure the method is declared on coderClazz itself (getDeclaredMethod does not search superclasses)
- Check coderClazz.getTypeParameters(): the arity of `of` must equal it exactly
- If a SecurityException is the cause, grant reflection permission or run without a restricting SecurityManager
Example fix
// before: no matching factory
class KVCoder<K, V> extends StructuredCoder<KV<K, V>> {
public static KVCoder of(Coder k, List<Coder> rest) { ... }
}
// after: one Coder arg per type parameter
class KVCoder<K, V> extends StructuredCoder<KV<K, V>> {
public static <K, V> KVCoder<K, V> of(Coder<K> keyCoder, Coder<V> valueCoder) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
static boolean hasValidOfFactory(Class<?> coderClazz) {
try {
Class<?>[] argTypes = new Class<?>[coderClazz.getTypeParameters().length];
java.util.Arrays.fill(argTypes, Coder.class);
coderClazz.getDeclaredMethod("of", argTypes);
return true;
} catch (NoSuchMethodException | SecurityException e) {
return false;
}
}
// assert hasValidOfFactory(MyCoder.class) before CoderProviders.fromStaticMethods(...) Type guard
static <T extends Coder<?>> boolean canRegisterFromStaticMethods(Class<T> coderClazz) {
try {
Class<?>[] argTypes = new Class<?>[coderClazz.getTypeParameters().length];
java.util.Arrays.fill(argTypes, Coder.class);
return coderClazz.isAssignableFrom(
coderClazz.getDeclaredMethod("of", argTypes).getReturnType());
} catch (NoSuchMethodException | SecurityException e) { return false; }
} Try / catch
try {
CoderProvider provider = CoderProviders.fromStaticMethods(rawType, coderClazz);
} catch (IllegalArgumentException e) {
// registration-time validation failure; fall back to an explicit coder
provider = CoderProviders.forCoder(typeDescriptor, coderInstance);
} Prevention
- Give every generic Coder class a static of(Coder, ...) with one arg per type parameter
- Remember getDeclaredMethod only sees methods declared on the class itself, not superclasses
- Check arity against getTypeParameters().length when copying factory patterns between coders
- Use CoderProviders.forCoder when a class has no suitable static factory
- Avoid SecurityManager-restricted environments for reflective registration
When it happens
Trigger: Passing a coderClazz to CoderProviders.fromStaticMethods(rawType, coderClazz) where the class has no `static Coder<T> of(Coder<?>, ...)` method matching its type-parameter count — e.g. `of` takes different argument types (TypeDescriptor, List<Coder<?>>), the factory is named `of` with wrong arity, or the class relies on a constructor instead of a static factory. Also thrown if a SecurityManager denies access via getDeclaredMethod.
Common situations: Registering a Coder whose factory signature follows an older Beam convention (e.g. of(TypeDescriptor, List)) rather than one Coder arg per type parameter; generic Coder classes with zero type parameters that nonetheless declare of(List<Coder<?>>); running under a SecurityManager or Java module restrictions that block reflection.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- cannot register Coder : method named 'of' with arguments of
- error when invoking Coder factory method
- 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/056964945a568102.
Report an issue: GitHub.