apache/beam · error · RuntimeException
Failed to parse row filter text proto
Error message
Failed to parse row filter text proto
What it means
BigtableIO.Read allows a RowFilter to be supplied as a text-format protobuf string via BigtableReadOptions.getRowFilterTextProto(). When TextFormat.parse fails on that string, a RuntimeException('Failed to parse row filter text proto') is thrown with the ParseException as cause. The string must be a valid text-encoding of a google.bigtable.v2.RowFilter.
Solutions
- Read the wrapped TextFormat.ParseException cause — it names the exact line/syntax problem
- Validate the string by parsing locally: TextFormat.parse(text, RowFilter.class) in a unit test
- Build the filter programmatically with RowFilter.newBuilder() and print with TextFormat.printer() to generate a known-valid string
- Escape special characters in regex/bytes fields per text-proto rules (e.g. quoted strings)
Example fix
// before
.withRowFilterTextProto("family_regex = 'stats.*'")
// after
.withRowFilterTextProto("family_regex: 'stats.*'") Defensive patterns
Strategy: validation
Validate before calling
String text = rowFilterTextProto.get();
try {
TextFormat.parse(text, com.google.bigtable.v2.RowFilter.class); // throws if invalid
} catch (TextFormat.ParseException e) {
throw new IllegalArgumentException("Invalid RowFilter text proto: " + e.getMessage(), e);
} Try / catch
try {
BigtableIO.read().withBigtableOptions(opts).withRowFilterTextProto(text).expand(...);
} catch (RuntimeException e) {
if (e.getCause() instanceof TextFormat.ParseException) {
// fix the text proto syntax named in the cause
}
throw e;
} Prevention
- Generate filter strings with RowFilter.newBuilder() + TextFormat.print() instead of hand-writing them
- Unit-test the filter string by parsing it before deploying
- Remember text-proto field syntax uses colons and quoted strings
When it happens
Trigger: Calling BigtableIO.read().withRowFilterTextProto(...) (or setting the pipeline option) with a string that is not valid text-proto: bad field names, missing escapes, invalid syntax, or wrong message nesting.
Common situations: Hand-written filter strings with typos, filters copied in wrong syntax (e.g. JSON instead of text proto), passing a regex with unescaped characters, forgetting to nest fields like chain { filters { ... } } correctly.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Aliased enumerations not currently supported.
- Any not yet supported
- Bigtable location must be in the following format…
- Cannot create creator for
- cannot encode a null
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8aabb541c63714ad.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableIO.java:1971
return readOptions;
}
public List<ByteKeyRange> getRanges() {
return readOptions.getKeyRanges().get();
}
public @Nullable RowFilter getRowFilter() {
RowFilter.Chain.Builder chain = RowFilter.Chain.newBuilder();
ValueProvider<RowFilter> rowFilterValueProvider = readOptions.getRowFilter();
if (rowFilterValueProvider != null && rowFilterValueProvider.isAccessible()) {
chain.addFilters(rowFilterValueProvider.get());
}
ValueProvider<String> textFilterValueProvider = readOptions.getRowFilterTextProto();
if (textFilterValueProvider != null && textFilterValueProvider.isAccessible()) {
try {
chain.addFilters(TextFormat.parse(textFilterValueProvider.get(), RowFilter.class));
} catch (TextFormat.ParseException e) {
throw new RuntimeException("Failed to parse row filter text proto", e);
}
}
switch (chain.getFiltersCount()) {
case 0:
return null;
case 1:
return chain.getFilters(0);
default:
return RowFilter.newBuilder().setChain(chain.build()).build();
}
}
public @Nullable Integer getMaxBufferElementCount() {
return readOptions.getMaxBufferElementCount();
}
public ValueProvider<String> getTableId() {View on GitHub (pinned to 12126d8942)