apache/beam · error · IllegalArgumentException

Unable to infer a coder and no Coder was specified. Please…

Error message

Unable to infer a coder and no Coder was specified. Please set a coder by invoking Create.withCoder() explicitly  or a schema by invoking Create.withSchema().

What it means

Create<T> needs a Coder for its elements. When no coder was supplied via withCoder() and no schema via withSchema(), Beam tries to infer one from the element classes; if inference fails with CannotProvideCoderException, expand() wraps the failure in this IllegalArgumentException. The library throws because a PCollection cannot exist without a coder.

Solutions

  1. Add .withCoder(MyCoder.of()) to the Create transform with an explicit coder for T.
  2. Alternatively call .withSchema(...) if T is a schema-annotated POJO/bean.
  3. Register a default coder via CoderRegistry.registerCoderForClass(MyPojo.class, MyPojoCoder.class) on the pipeline.
  4. If T is a schema class, annotate it with @DefaultSchema or implement Serializable and use a SerializableCoder.

Example fix

// before
p.apply(Create.of(myPojoList)); // CannotProvideCoderException for MyPojo
// after
p.apply(Create.of(myPojoList).withCoder(SerializableCoder.of(MyPojo.class)));
Defensive patterns

Strategy: validation

Validate before calling

try { pipeline.getCoderRegistry().getCoder(javaType); } catch (CannotProvideCoderException e) { /* supply withCoder/withSchema */ }

Type guard

boolean canInferCoder(Pipeline p, Class<?> t) { try { p.getCoderRegistry().getCoder(TypeDescriptor.of(t)); return true; } catch (CannotProvideCoderException e) { return false; } }

Try / catch

try { p.apply(Create.of(elems)); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Unable to infer a coder")) { p.apply(Create.of(elems).withCoder(SerializableCoder.of(MyType.class))); } else throw e; }

Prevention

When it happens

Trigger: Calling Create.of(elems) where elements' runtime class has no registered/default coder (e.g. a POJO without schema inference support, an interface type, or Object), and neither withCoder() nor withSchema() was called.

Common situations: Create.of(someListOfCustomPojo) before registering a schema; Create.of(mixedTypeList) inferred as Object; using types like java.lang.Object or generic type-erased collections in tests or quick prototypes.

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/33572904bec84b67. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/Create.java:397

            try {
              coder =
                  SchemaCoder.of(
                      schemaRegistry.getSchema(typeDescriptor.get()),
                      typeDescriptor.get(),
                      schemaRegistry.getToRowFunction(typeDescriptor.get()),
                      schemaRegistry.getFromRowFunction(typeDescriptor.get()));
            } catch (NoSuchSchemaException e) {
              // No schema registered.
            }
            if (coder == null) {
              coder = coderRegistry.getCoder(typeDescriptor.get());
            }
          } else {
            coder = getDefaultCreateCoder(coderRegistry, schemaRegistry, elems);
          }
        }
      } catch (CannotProvideCoderException e) {
        throw new IllegalArgumentException(
            "Unable to infer a coder and no Coder was specified. "
                + "Please set a coder by invoking Create.withCoder() explicitly "
                + " or a schema by invoking Create.withSchema().",
            e);
      }
      try {
        if (!alwaysUseRead) {
          int numElements = Iterables.size(elems);
          if (numElements == 0) {
            return input
                .apply(Impulse.create())
                .apply(
                    FlatMapElements.via(
                        new SimpleFunction<byte[], Iterable<T>>() {
                          @Override
                          public Iterable<T> apply(byte[] input) {
                            return Collections.emptyList();
                          }

View on GitHub (pinned to 12126d8942)