apache/iceberg · error · AlreadyExistsException

Namespace already exists: %s

Error message

Namespace already exists: %s

What it means

AlreadyExistsException from BigQueryMetastoreClientImpl.internalCreate when the BigQuery datasets.insert call reports the dataset already exists (google HTTP AlreadyExistsException). The client converts this into an Iceberg AlreadyExistsException naming the dataset id.

Source

Thrown at bigquery/src/main/java/org/apache/iceberg/gcp/bigquery/BigQueryMetastoreClientImpl.java:179

              bigqueryOptions.getOpenTelemetryTracer());
    } catch (BigQueryRetryHelper.BigQueryRetryHelperException e) {
      handleBigQueryRetryException(e);
    }
    return response;
  }

  private Dataset internalCreate(Dataset dataset) {
    try {
      HttpResponse response =
          client
              .datasets()
              .insert(dataset.getDatasetReference().getProjectId(), dataset)
              .executeUnparsed();
      return convertExceptionIfUnsuccessful(response).parseAs(Dataset.class);
    } catch (IOException e) {
      throw new RuntimeIOException(e);
    } catch (AlreadyExistsException e) {
      throw new AlreadyExistsException("Namespace already exists: %s", dataset.getId());
    }
  }

  @Override
  public Dataset load(DatasetReference datasetReference) {
    try {
      HttpResponse response =
          client
              .datasets()
              .get(datasetReference.getProjectId(), datasetReference.getDatasetId())
              .executeUnparsed();
      if (response.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
        throw new NoSuchNamespaceException(
            "Namespace does not exist: %s", datasetReference.getDatasetId());
      }

      return convertExceptionIfUnsuccessful(response).parseAs(Dataset.class);
    } catch (IOException e) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check namespaceExists / dataset existence first and skip creation if present
  2. Catch AlreadyExistsException and treat as success for idempotent setup scripts
  3. Use unique dataset ids per environment/run when creating throwaway datasets
  4. Serialize namespace creation through a single job or lock

Example fix

// before
client.create(dataset); // throws if exists
// after
try {
  client.create(dataset);
} catch (AlreadyExistsException e) {
  // dataset already provisioned; ignore
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!client.namespaceExists(datasetId)) { client.create(dataset); }

Try / catch

try { client.create(dataset); } catch (AlreadyExistsException e) { /* idempotent no-op */ }

Prevention

When it happens

Trigger: Calling createNamespace / client.create for a dataset id that already exists in the project; two concurrent createNamespace calls racing to create the same dataset.

Common situations: Rerunning an initialization script without idempotency, retry logic that re-issues create after a timeout where the first request actually succeeded, concurrent CI pipelines creating the same namespace.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/197708cf473d015b. Report an issue: GitHub.