apache/beam · error · IllegalArgumentException

You must include a descriptorPath or a proto Schema but not…

Error message

You must include a descriptorPath or a proto Schema but not both.

What it means

KafkaWriteSchemaTransformProvider (PROTO format) requires the proto message to be described exactly one way: either via a file descriptorPath or an inline proto Schema. Supplying both at once makes the intended source ambiguous, so expand() throws this IllegalArgumentException as an input validation guard.

Solutions

  1. Provide only one of fileDescriptorPath or schema in the transform configuration.
  2. Clear the other field so exactly one descriptor source remains.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at sdks/java/io/kafka/src/main/java/org/apache/beam/sdk/io/kafka/KafkaWriteSchemaTransformProvider.java:220 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at sdks/java/io/kafka/src/main/java/org/apache/beam/sdk/io/kafka/KafkaWriteSchemaTransformProvider.java:220

        if (numFields != 1) {
          throw new IllegalArgumentException("Expecting exactly one field, found " + numFields);
        }
        if (!inputSchema.getField(0).getType().equals(Schema.FieldType.BYTES)) {
          throw new IllegalArgumentException(
              "The input schema must have exactly one field of type byte.");
        }
        toBytesFn = getRowToRawBytesFunction(inputSchema.getField(0).getName());
      } else if (configuration.getFormat().equals("JSON")) {
        toBytesFn = JsonUtils.getRowToJsonBytesFunction(inputSchema);
      } else if (configuration.getFormat().equals("PROTO")) {
        String descriptorPath = configuration.getFileDescriptorPath();
        String schema = configuration.getSchema();
        String messageName = configuration.getMessageName();
        if (messageName == null) {
          throw new IllegalArgumentException("Expecting messageName to be non-null.");
        }
        if (descriptorPath != null && schema != null) {
          throw new IllegalArgumentException(
              "You must include a descriptorPath or a proto Schema but not both.");
        } else if (descriptorPath != null) {
          toBytesFn = ProtoByteUtils.getRowToProtoBytes(descriptorPath, messageName);
        } else if (schema != null) {
          toBytesFn = ProtoByteUtils.getRowToProtoBytesFromSchema(schema, messageName);
        } else {
          throw new IllegalArgumentException(
              "At least a descriptorPath or a proto Schema is required.");
        }
      } else {
        if (configuration.getProducerConfigUpdates() != null
            && configuration.getProducerConfigUpdates().containsKey("schema.registry.url")) {
          toGenericRecordsFn = AvroUtils.getRowToGenericRecordFunction(avroSchema);
          toBytesFn = null;
        } else {
          toBytesFn = AvroUtils.getRowToAvroBytesFunction(inputSchema);
        }
      }

View on GitHub (pinned to 12126d8942)