apache/beam · error · ApiException

NOT_FOUND

NOT_FOUND

Error message

NOT_FOUND

What it means

The storage-write create/lookup path in FakeDatasetService wraps any IOException in a gRPC ApiException with status NOT_FOUND, because the fake does not reproduce BigQuery's exact error codes (see TODO(relax) comment). Any failure to resolve the stream/table surfaces as NOT_FOUND.

Solutions

  1. Verify the table (and dataset) exist in the fake via createTable/createDataset before creating write streams
  2. Check the stream name/format passed to the storage API
  3. Inspect the wrapped cause (e.getCause()) to see the real IOException since the status is approximated

Example fix

// before
stream = client.createWriteStream("projects/p/datasets/d/tables/missing/streams/_default"); // NOT_FOUND
// after
service.createTable(ref, schema);
stream = client.createWriteStream("projects/p/datasets/d/tables/t/streams/_default");
Defensive patterns

Strategy: retry

Validate before calling

// Ensure parent table exists before creating/using a write stream
try {
  service.getTable(tableRef);
} catch (IOException | InterruptedException e) {
  throw new IllegalStateException("parent table missing in fake: " + tableRef, e);
}

Try / catch

try {
  stream = client.createWriteStream(streamName);
} catch (ApiException e) {
  if (e.getStatusCode().getCode() == io.grpc.StatusCode.NOT_FOUND) {
    throw new IllegalStateException("stream/table not found in fake; check test setup", e.getCause());
  }
  throw e;
}

Prevention

When it happens

Trigger: BatchCreateWriteStream / stream creation when the referenced table or dataset does not exist in the fake, or an internal IOException occurs while setting up the write stream.

Common situations: Writing to a stream for a table that was never created in the fake service; typos in dataset/table ids in test setup; a fake-side IO failure being masked as NOT_FOUND.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/testing/FakeDatasetService.java:752

  public WriteStream createWriteStream(String tableUrn, WriteStream.Type type)
      throws InterruptedException {
    try {
      TableReference tableReference =
          BigQueryHelpers.parseTableUrn(BigQueryHelpers.stripPartitionDecorator(tableUrn));
      synchronized (FakeDatasetService.class) {
        TableContainer tableContainer =
            getTableContainer(
                tableReference.getProjectId(),
                tableReference.getDatasetId(),
                tableReference.getTableId());
        String streamName = UUID.randomUUID().toString();
        Stream stream = new Stream(streamName, tableContainer, type);
        writeStreams.put(streamName, stream);
        return stream.toWriteStream();
      }
    } catch (IOException e) {
      // TODO(relax): Return the exact error that BigQuery returns.
      throw new ApiException(e, GrpcStatusCode.of(Status.Code.NOT_FOUND), false);
    }
  }

  @Override
  @Nullable
  public com.google.cloud.bigquery.storage.v1.TableSchema getWriteStreamSchema(String streamName) {
    synchronized (FakeDatasetService.class) {
      @Nullable Stream stream = writeStreams.get(streamName);
      if (stream != null) {
        return stream.toWriteStream().getTableSchema();
      }
    }
    // TODO(relax): Return the exact error that BigQuery returns.
    throw new ApiException(null, GrpcStatusCode.of(Status.Code.NOT_FOUND), false);
  }

  @Override
  public StreamAppendClient getStreamAppendClient(

View on GitHub (pinned to 12126d8942)