{"record":{"id":"2ca7b92150279092","repo":"apache/beam","slug":"invalid-encoded-string-length","errorCode":null,"errorMessage":"Invalid encoded string length: {}","messagePattern":"Invalid encoded string length: (.+?)","errorType":"exception","errorClass":"CoderException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/StringUtf8Coder.java","lineNumber":57,"sourceCode":"  public static StringUtf8Coder of() {\n    return INSTANCE;\n  }\n\n  /////////////////////////////////////////////////////////////////////////////\n\n  private static final StringUtf8Coder INSTANCE = new StringUtf8Coder();\n  private static final TypeDescriptor<String> TYPE_DESCRIPTOR = new TypeDescriptor<String>() {};\n\n  private static void writeString(String value, OutputStream dos) throws IOException {\n    byte[] bytes = value.getBytes(StandardCharsets.UTF_8);\n    VarInt.encode(bytes.length, dos);\n    dos.write(bytes);\n  }\n\n  private static String readString(InputStream dis) throws IOException {\n    int len = VarInt.decodeInt(dis);\n    if (len < 0) {\n      throw new CoderException(\"Invalid encoded string length: \" + len);\n    }\n    byte[] bytes = new byte[len];\n    ByteStreams.readFully(dis, bytes);\n    return new String(bytes, StandardCharsets.UTF_8);\n  }\n\n  private StringUtf8Coder() {}\n\n  @Override\n  public void encode(String value, OutputStream outStream) throws IOException {\n    encode(value, outStream, Context.NESTED);\n  }\n\n  @Override\n  public void encode(String value, OutputStream outStream, Context context) throws IOException {\n    if (value == null) {\n      throw new CoderException(\"cannot encode a null String\");\n    }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/StringUtf8Coder.java#L39-L75","documentation":"StringUtf8Coder.decode reads a VarInt length prefix followed by that many UTF-8 bytes. A negative decoded length means the stream is corrupt or misaligned — no valid string has negative length, so the coder refuses and throws CoderException. This guards against decoding garbage or decoding at the wrong stream offset.","triggerScenarios":"Decoding a byte stream not produced by StringUtf8Coder (e.g. raw UTF-8 bytes without the VarInt length prefix); decoding from the wrong offset in a concatenated or multiplexed stream; truncated or bit-rotted data where VarInt bytes decode to a negative value.","commonSituations":"Mixing coder versions between pipeline stages; replaying old serialized data written in a different format; hand-crafted test byte arrays missing the length prefix; seeking into the middle of an encoded stream.","solutions":["Ensure the stream was written by StringUtf8Coder.encode(), including its VarInt length prefix.","Verify the decode offset: start at the exact position where encoding began.","Regenerate or re-serialize data with the same Beam/coder version that wrote it.","Catch CoderException and log/dump the offending bytes to diagnose corruption."],"exampleFix":"// before\nString s = StringUtf8Coder.of().decode(rawUtf8Stream);\n// after\nByteArrayOutputStream bos = new ByteArrayOutputStream();\nStringUtf8Coder.of().encode(myString, bos);\nString s = StringUtf8Coder.of().decode(new ByteArrayInputStream(bos.toByteArray()));","handlingStrategy":"try-catch","validationCode":"in.mark(1);\nint first = in.read();\nin.reset();\nif (first == -1) throw new IllegalStateException(\"Empty stream, not a StringUtf8-encoded value\");","typeGuard":"static boolean looksLikeLengthPrefixed(byte[] data) {\n  return data != null && data.length >= 1;\n}","tryCatchPattern":"try {\n  String s = StringUtf8Coder.of().decode(inStream);\n} catch (CoderException e) {\n  log.error(\"Corrupt or misaligned string encoding\", e);\n  throw new DataCorruptionException(e);\n}","preventionTips":["Always round-trip through encode()/decode() of the same coder; never feed raw UTF-8 to decode.","Keep the same coder for a PCollection across pipeline versions; avoid ad-hoc setCoder changes on existing data.","When multiplexing streams, decode from exact element boundaries.","Add checksums/lengths at the transport layer to detect truncation early."],"tags":["java","beam","coder","deserialization","corrupt-data"],"backgroundTag":"invalid-argument-format","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}