apache/beam · error · IllegalArgumentException

Invalid startOffset entry: "". Expected format is…

Error message

Invalid startOffset entry: "". Expected format is "key=value".

What it means

DebeziumIO's external transform registrar validates each --startOffset command-line entry as a key=value pair. split("=", 2) must yield exactly two parts; an empty or '='-less string fails. This guards the map built from startOffset entries.

Solutions

  1. Inspect the --startOffset arguments and remove/fix any entry without '='.
  2. Quote entries in shell scripts so empty expansions are skipped: use arrays and conditional appends.
  3. Validate entries in the pipeline launcher before invoking buildExternal.

Example fix

// before
--startOffset="" --startOffset=partition=0
// after
--startOffset=partition=0
Defensive patterns

Strategy: validation

Validate before calling

for (String prop : startOffsetArgs) {
  if (prop == null || !prop.contains("=")) {
    throw new IllegalArgumentException("startOffset entries must be key=value, got: " + prop);
  }
}

Try / catch

try {
  DebeziumIO.buildExternal(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Invalid startOffset entry")) {
    // sanitize args: drop entries without '='
  }
}

Prevention

When it happens

Trigger: Passing an empty string or a string with no '=' at all (split("=", 2) yields length 1) in configuration.startOffset when building the external Debezium transform.

Common situations: Trailing empty element from a shell expansion (e.g. an environment variable like OFFSETS="k1=v1,$EXTRA" where EXTRA is empty expanded to --startOffset twice), hand-typed CLI flags with a missing '='.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/io/debezium/src/main/java/org/apache/beam/io/debezium/DebeziumTransformRegistrar.java:142

      DebeziumIO.Read<String> readTransform =
          DebeziumIO.readAsJson().withConnectorConfiguration(connectorConfiguration);

      if (configuration.maxNumberOfRecords != null) {
        readTransform =
            readTransform.withMaxNumberOfRecords(configuration.maxNumberOfRecords.intValue());
      }

      if (configuration.maxTimeToRun != null) {
        readTransform = readTransform.withMaxTimeToRun(configuration.maxTimeToRun);
      }

      if (configuration.startOffset != null) {
        Map<String, Object> startOffsetMap = new HashMap<>();
        for (String property : configuration.startOffset) {
          String[] parts = property.split("=", 2);
          if (parts.length != 2) {
            throw new IllegalArgumentException(
                "Invalid startOffset entry: \""
                    + property
                    + "\". Expected format is \"key=value\".");
          }
          String key = parts[0];
          String value = parts[1];
          try {
            startOffsetMap.put(key, Long.parseLong(value));
          } catch (NumberFormatException e) {
            startOffsetMap.put(key, value);
          }
        }
        readTransform = readTransform.withStartOffset(startOffsetMap);
      }

      if (configuration.offsetStoragePath != null) {
        readTransform =
            readTransform.withOffsetRetainer(

View on GitHub (pinned to 12126d8942)