apache/superset · error · DatasetAccessDeniedError

You don't have access to this dataset.

Error message

You don't have access to this dataset.

What it means

DatasetAccessDeniedError (HTTP 403, "You don't have access to this dataset.") is raised by the dataset duplicate command when security_manager.raise_for_access(datasource=base_model) throws. Duplicating reads the base dataset's definition, so the caller needs datasource access to it — not just a valid base_model_id.

Source

Thrown at superset/commands/dataset/duplicate.py:135

        ]
        db.session.add_all(metrics)
        table.metrics = metrics

        return table

    def validate(self) -> None:
        exceptions: list[ValidationError] = []
        base_model_id = self._properties["base_model_id"]
        duplicate_name = self._properties["table_name"]

        base_model = DatasetDAO.find_by_id(base_model_id)
        if not base_model:
            exceptions.append(DatasetNotFoundError())
        else:
            try:
                security_manager.raise_for_access(datasource=base_model)
            except SupersetSecurityException as ex:
                raise DatasetAccessDeniedError() from ex
            self._base_model = base_model

        if self._base_model and self._base_model.kind != "virtual":
            exceptions.append(DatasourceTypeInvalidError())

        # Use the shared uniqueness check (same as create/update) rather than a
        # name-only filtered lookup: it scopes to the base model's
        # database/schema, is catalog-NULL-aware, and bypasses the soft-delete
        # visibility filter. A filtered lookup misses a soft-deleted twin, so
        # the duplicate would proceed and either hit a DB constraint as an
        # opaque IntegrityError or — where no constraint applies (the
        # model-level UniqueConstraint is metadata-only and the legacy
        # _customer_location_uc is NULL-leaky) — create an active twin that
        # permanently blocks restore of the soft-deleted dataset.
        if base_model and not DatasetDAO.validate_uniqueness(
            base_model.database,
            Table(duplicate_name, base_model.schema, base_model.catalog),
        ):

View on GitHub (pinned to f4587218dd)

Solutions

  1. Grant the calling user access to the base dataset (or its database) via roles/ownership, then retry.
  2. Have the dataset's owner or an Admin perform the duplication and transfer ownership of the copy.
  3. Verify access first with GET /api/v1/dataset/<base_model_id> — a 403/404 there predicts this failure.
Defensive patterns

Strategy: validation

Validate before calling

# Check datasource access before offering duplication
from superset import security_manager

def can_duplicate(base_model) -> bool:
    if base_model is None:
        return False
    try:
        security_manager.raise_for_access(datasource=base_model)
        return True
    except Exception:
        return False

Try / catch

from superset.commands.dataset.exceptions import DatasetAccessDeniedError
try:
    DuplicateDatasetCommand(base_id, properties).run()
except DatasetAccessDeniedError:
    # 403: user cannot read the source dataset — route to its owner; never retry
    request_from_owner(base_id)

Prevention

When it happens

Trigger: POST /api/v1/dataset/duplicate with a base_model_id the caller cannot access (no dataset access grant, no role covering that database, RLS rules aside — this is the datasource gate); scripts guessing dataset ids.

Common situations: Gamma users duplicating datasets outside their granted datasources; cross-team copies attempted with read-restricted connections; tokens scoped to other resources.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/4e13b56ab700255a. Report an issue: GitHub.