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 CreateTimestamped.withCoder() explicitly.

What it means

CreateTimestamped<T> must code both the TimestampedValue elements and the output PCollection; when no coder is given via withCoder() and inference from T fails (CannotProvideCoderException), expand() throws this IllegalArgumentException. The message specifically directs users to CreateTimestamped.withCoder().

Solutions

  1. Add .withCoder(MyCoder.of()) (or TimestampedValueCoder.of(inner)) to the CreateTimestamped transform.
  2. Register a default coder for T in the pipeline's CoderRegistry.
  3. For POJOs, use .withSchema(...) or annotate the class so schema inference can supply a coder.
  4. Extract elements into an explicitly-typed variable to help coder inference before building the transform.

Example fix

// before
p.apply(Create.timestamped(TimestampedValue.of(myObj, Instant.now()))); // inference fails
// after
p.apply(Create.timestamped(TimestampedValue.of(myObj, Instant.now()))
    .withCoder(SerializableCoder.of(MyObj.class)));
Defensive patterns

Strategy: validation

Validate before calling

try { p.getCoderRegistry().getCoder(TypeDescriptor.of(MyType.class)); } catch (CannotProvideCoderException e) { /* chain .withCoder */ }

Try / catch

try { p.apply(Create.timestamped(vals)); } catch (IllegalArgumentException e) { if (e.getMessage().contains("CreateTimestamped.withCoder")) { p.apply(Create.timestamped(vals).withCoder(myCoder)); } else throw e; }

Prevention

When it happens

Trigger: Calling Create.timestamped(...) (or CreateTimestamped.of) with elements whose type has no default coder (POJO, interface, Object) and not chaining .withCoder(...).

Common situations: Creating timestamped test data with custom types; generics/type-erased collections passed to Create.timestamped; forgetting that TimestampedValueCoder still needs an inner coder for T.

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/05d12bfc8c4fdbb2. Report an issue: GitHub.

Appendix: source

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

          }
          if (coder == null) {
            coder = coderRegistry.getCoder(typeDescriptor.get());
          }
        } else {
          Iterable<T> rawElements =
              Iterables.transform(timestampedElements, TimestampedValue::getValue);
          coder = getDefaultCreateCoder(coderRegistry, schemaRegistry, rawElements);
        }

        PCollection<TimestampedValue<T>> intermediate =
            Pipeline.applyTransform(
                input, Create.of(timestampedElements).withCoder(TimestampedValueCoder.of(coder)));

        PCollection<T> output = intermediate.apply(ParDo.of(new ConvertTimestamps<>()));
        output.setCoder(coder);
        return output;
      } catch (CannotProvideCoderException e) {
        throw new IllegalArgumentException(
            "Unable to infer a coder and no Coder was specified. "
                + "Please set a coder by invoking CreateTimestamped.withCoder() explicitly.",
            e);
      }
    }

    /////////////////////////////////////////////////////////////////////////////

    /** The timestamped elements of the resulting PCollection. */
    private final transient Iterable<TimestampedValue<T>> timestampedElements;

    /** The coder used to encode the values to and from a binary representation. */
    private final transient Optional<Coder<T>> elementCoder;

    /** The value type. */
    private final transient Optional<TypeDescriptor<T>> typeDescriptor;

    private TimestampedValues(

View on GitHub (pinned to 12126d8942)