apache/beam · error · IllegalArgumentException
For a cycling sequence generator, both 'start' and 'end'…
Error message
For a cycling sequence generator, both 'start' and 'end' must be specified.
What it means
A sequence generator needs an explicit range to cycle over. If only one of 'fields.<name>.start' and 'fields.<name>.end' is provided (the other missing), the cycle bounds cannot be computed and an IllegalArgumentException is thrown. Note: if BOTH are missing, the generator falls back to using the row index.
Solutions
- Specify both 'fields.<name>.start' and 'fields.<name>.end' in the table properties.
- Remove both keys if you want the default index-based generator.
- If an ever-increasing counter is desired, omit both and use the returned index generator, or set a large 'end'.
Example fix
// before
'{"fields":{"id":{"kind":"sequence","start":1}}}'
// after
'{"fields":{"id":{"kind":"sequence","start":1,"end":100}}}' Defensive patterns
Strategy: validation
Validate before calling
JsonNode start = props.path("fields." + name + ".start");
JsonNode end = props.path("fields." + name + ".end");
if (start.isMissingNode() != end.isMissingNode()) {
throw new IllegalArgumentException(name + ": both start and end required");
} Try / catch
try { buildRowFn(props); } catch (IllegalArgumentException e) { /* add missing bound or remove both */ } Prevention
- Always emit start and end together when templating sequence configs.
- Omit both keys when index-based generation is intended.
When it happens
Trigger: Setting fields.<name>.start without fields.<name>.end (or vice versa) with kind='sequence' on an integer datagen field.
Common situations: Partial copy-paste of TBLPROPERTIES JSON; someone removed the 'end' key assuming 'start' alone is an incrementing counter.
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
- A 'datagen' table requires either 'rows-per-second' (for…
- Data generator requires a defined SQL type. Beam type
- For 'event-time' behavior, 'event-time.timestamp-column'…
- For sequence generator, 'start
- 'max-past' must be a positive long value.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0e87144fd63bf07f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datagen/DataGeneratorRowFn.java:132
}
if ("sequence".equalsIgnoreCase(kind)) {
if (!SqlTypeName.INT_TYPES.contains(sqlTypeName)) {
throw new IllegalArgumentException(
String.format(
"The 'sequence' generator for integers only supports integer types, but field '%s' is of type '%s'.",
field.getName(), sqlTypeName));
}
JsonNode startNode = properties.path("fields." + fieldName + ".start");
JsonNode endNode = properties.path("fields." + fieldName + ".end");
if (startNode.isMissingNode() && endNode.isMissingNode()) {
return (index) -> index;
}
if (startNode.isMissingNode() || endNode.isMissingNode()) {
throw new IllegalArgumentException(
"For a cycling sequence generator, both 'start' and 'end' must be specified.");
}
long start = startNode.asLong(0L);
long end = endNode.asLong(Long.MAX_VALUE);
if (start > end) {
throw new IllegalArgumentException(
String.format(
"For sequence generator, 'start' (%d) cannot be greater than 'end' (%d).",
start, end));
}
long cycleLength = end - start + 1;
switch (sqlTypeName) {
case INTEGER:
return (index) -> (int) (start + (index % cycleLength));
case SMALLINT:
return (index) -> (short) (start + (index % cycleLength));View on GitHub (pinned to 12126d8942)