apache/beam · error · CoderException

error when decoding a textual integer

Error message

error when decoding a textual integer

What it means

TextualIntegerCoder.decode first decodes a UTF-8 string, then parses it with Integer.valueOf. If the string is not a valid signed 32-bit decimal integer (empty, non-numeric, or beyond Integer range), the NumberFormatException is caught and rethrown as CoderException with this message and the original as cause.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/TextualIntegerCoder.java:67

    if (value == null) {
      throw new CoderException("cannot encode a null Integer");
    }
    String textualValue = value.toString();
    StringUtf8Coder.of().encode(textualValue, outStream, context);
  }

  @Override
  public Integer decode(InputStream inStream) throws IOException, CoderException {
    return decode(inStream, Context.NESTED);
  }

  @Override
  public Integer decode(InputStream inStream, Context context) throws IOException, CoderException {
    String textualValue = StringUtf8Coder.of().decode(inStream, context);
    try {
      return Integer.valueOf(textualValue);
    } catch (NumberFormatException exn) {
      throw new CoderException("error when decoding a textual integer", exn);
    }
  }

  @Override
  public void verifyDeterministic() {
    StringUtf8Coder.of().verifyDeterministic();
  }

  @Override
  public TypeDescriptor<Integer> getEncodedTypeDescriptor() {
    return TYPE_DESCRIPTOR;
  }

  @Override
  protected long getEncodedElementByteSize(Integer value) throws Exception {
    if (value == null) {
      throw new CoderException("cannot encode a null Integer");
    }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the stream was written by TextualIntegerCoder.encode (decimal string with StringUtf8 length prefix).
  2. Log the failing string from the exception cause to identify the bad data.
  3. Use VarIntCoder or BigEndianIntegerCoder to match the original binary format if data was not textual.
  4. Switch to a Long coder (e.g. TextualLongCoder) if values may exceed int range.

Example fix

// before
Integer v = TextualIntegerCoder.of().decode(in);
// after
try {
  Integer v = TextualIntegerCoder.of().decode(in);
} catch (CoderException e) {
  throw new IllegalStateException("Non-numeric or out-of-range data in stream", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

String s = decodeStringSomehow(in);
if (s == null || !s.matches("-?\\d+")) {
  throw new IllegalArgumentException("Not a textual integer: " + s);
}

Type guard

static boolean isParsableInt(String s) {
  try { Integer.parseInt(s); return true; } catch (NumberFormatException e) { return false; }
}

Try / catch

try {
  Integer v = TextualIntegerCoder.of().decode(in);
} catch (CoderException e) {
  Throwable cause = e.getCause();
  if (cause instanceof NumberFormatException) {
    throw new DataCorruptionException("Non-numeric data in stream: " + cause.getMessage(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Decoding bytes written by a different coder (e.g. binary VarIntCoder instead of textual); corrupted or truncated stream producing garbage text; values exceeding Integer.MAX_VALUE/MIN_VALUE; hand-edited text data read back with this coder.

Common situations: Switching an element's coder between VarIntCoder and TextualIntegerCoder so old data no longer decodes; reading external text with non-numeric values into an Integer-coded PCollection; formatted data with separators like commas.

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/5649b908116e5ff1. Report an issue: GitHub.