apache/beam · error · IllegalArgumentException

Unable to infer coder for output of parseFn. Specify it…

Error message

Unable to infer coder for output of parseFn. Specify it explicitly using .withCoder().

What it means

After ruling out GenericRecord, inferCoder tries to derive the Coder for parseFn's output type from the pipeline's CoderRegistry. If the registry cannot provide a coder (unregistered custom type, non-codable fields, generic types), ParquetIO throws IllegalArgumentException advising an explicit coder via .withCoder().

Solutions

  1. Call .withCoder(myCoder) explicitly on the ParquetIO.Read builder.
  2. Register a coder for the output type via coderRegistry.registerCoderForClass(...).
  3. Make the output a simple Serializable/Avro/POJO type the registry can infer automatically.

Example fix

// before
ParquetIO.<MyPojo>readFrom(path).withParseFn(ParquetReadTest::parse)
// after
ParquetIO.<MyPojo>readFrom(path)
  .withParseFn(ParquetReadTest::parse)
  .withCoder(SerializableCoder.of(MyPojo.class))
Defensive patterns

Strategy: validation

Validate before calling

try { coderRegistry.getCoder(TypeDescriptors.outputOf(parseFn)); } catch (CannotProvideCoderException e) { /* add .withCoder(...) */ }

Prevention

When it happens

Trigger: Expanding a ParquetIO read with a parseFn whose output type T has no registered/default coder — e.g. a custom POJO without a Coder, ambiguous generic types, or a type the registry's TypeDescriptor-based inference cannot handle.

Common situations: Custom domain objects not registered with the CoderRegistry; using Avro/POJO types needing explicit coders; Kotlin/complex generic outputs confusing TypeDescriptors.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/io/parquet/src/main/java/org/apache/beam/sdk/io/parquet/ParquetIO.java:594

     *
     * @param coderRegistry the {@link org.apache.beam.sdk.Pipeline}'s CoderRegistry to identify
     *     Coder for expected output type of {@link #getParseFn()}
     */
    private Coder<T> inferCoder(CoderRegistry coderRegistry) {
      if (isGenericRecordOutput()) {
        throw new IllegalArgumentException("Parse can't be used for reading as GenericRecord.");
      }

      // Use explicitly provided coder
      if (getCoder() != null) {
        return getCoder();
      }

      // If not GenericRecord infer it from ParseFn.
      try {
        return coderRegistry.getCoder(TypeDescriptors.outputOf(getParseFn()));
      } catch (CannotProvideCoderException e) {
        throw new IllegalArgumentException(
            "Unable to infer coder for output of parseFn. Specify it explicitly using .withCoder().",
            e);
      }
    }
  }

  /** Implementation of {@link #readFiles(Schema)}. */
  @AutoValue
  public abstract static class ReadFiles
      extends PTransform<PCollection<ReadableFile>, PCollection<GenericRecord>> {

    abstract @Nullable Schema getSchema();

    abstract @Nullable GenericData getAvroDataModel();

    abstract @Nullable Schema getEncoderSchema();

    abstract @Nullable Schema getProjectionSchema();

View on GitHub (pinned to 12126d8942)