apache/beam · warning

Error Handling is partially supported when using…

Error message

Error Handling is partially supported when using FILE_LOADS. Consider using STORAGE_WRITE_API or STORAGE_API_AT_LEAST_ONCE

What it means

Bad-record error handling (withBadRecordRouter / error collection) is only fully implemented for the Storage API write methods. When FILE_LOADS is used with a non-throwing bad record router, only partial error handling is available, so the sink warns users to switch methods for complete error handling.

Solutions

  1. Switch the write method to Method.STORAGE_WRITE_API or Method.STORAGE_API_AT_LEAST_ONCE for full error handling
  2. Keep the default ThrowingBadRecordRouter if FILE_LOADS must be used and partial handling is unacceptable
  3. Review the partial FILE_LOADS error semantics in the BigQueryIO docs before relying on routed records

Example fix

// before
BigQueryIO.writeTableRows().to(table).withMethod(Method.FILE_LOADS).withBadRecordRouter(customRouter)
// after
BigQueryIO.writeTableRows().to(table).withMethod(Method.STORAGE_WRITE_API).withBadRecordRouter(customRouter)
Defensive patterns

Strategy: validation

Validate before calling

if (method == Method.FILE_LOADS && !(badRecordRouter instanceof ThrowingBadRecordRouter)) { /* expect only partial error handling */ }

Prevention

When it happens

Trigger: A FILE_LOADS write whose getBadRecordRouter() is not a ThrowingBadRecordRouter — i.e. a custom/routing BadRecordRouter was configured via withBadRecordRouter(...) while keeping the batch file-load method.

Common situations: Teams adding data-quality error collection to an existing batch BigQuery load pipeline instead of migrating to the Storage API write path that fully supports bad-record routing.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryIO.java:4227

                .withSuccessfulInsertsPropagation(getPropagateSuccessful())
                .withDeterministicRecordIdFn(getDeterministicRecordIdFn())
                .withKmsKey(getKmsKey());
        return input.apply(streamingInserts);
      } else if (method == Write.Method.FILE_LOADS) {
        checkArgument(
            getFailedInsertRetryPolicy() == null,
            "Record-insert retry policies are not supported when using BigQuery load jobs.");

        if (getUseAvroLogicalTypes()) {
          checkArgument(
              rowWriterFactory.getOutputType() == OutputType.AvroGenericRecord,
              "useAvroLogicalTypes can only be set with Avro output.");
        }
        checkArgument(
            !getPropagateSuccessfulStorageApiWrites(),
            "withPropagateSuccessfulStorageApiWrites only supported when using storage api writes.");
        if (!(getBadRecordRouter() instanceof ThrowingBadRecordRouter)) {
          LOG.warn(
              "Error Handling is partially supported when using FILE_LOADS. Consider using STORAGE_WRITE_API or STORAGE_API_AT_LEAST_ONCE");
        }

        // Batch load handles wrapped json string value differently than the other methods. Raise a
        // warning when applies.
        ValueProvider<String> jsonSchema = getJsonSchema();
        if (jsonSchema != null && jsonSchema.isAccessible()) {
          JsonElement schema = JsonParser.parseString(jsonSchema.get());
          if (!schema.getAsJsonObject().keySet().isEmpty() && hasJsonTypeInSchema(schema)) {
            if (rowWriterFactory.getOutputType() == OutputType.JsonTableRow) {
              LOG.warn(
                  "Found JSON type in TableSchema for 'FILE_LOADS' write method. \n"
                      + "Make sure the TableRow value is a Jackson JsonNode to ensure the read as a "
                      + "JSON type. Otherwise it will read as a raw (escaped) string.\n"
                      + "See https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-json#limitations "
                      + "for limitations.");
            } else if (rowWriterFactory.getOutputType() == OutputType.AvroGenericRecord) {
              LOG.warn(

View on GitHub (pinned to 12126d8942)