apache/superset · error · MissingOAuth2TokenError

Missing OAuth2 token

Error message

Missing OAuth2 token

What it means

MissingOAuth2TokenError is raised in validate() when pinging the database engine raises, the database has OAuth2 enabled (is_oauth2_enabled()), and the engine spec classifies the error via needs_oauth2(err) as a missing/expired OAuth2 token. Superset uses OAuth2 for engines like Databricks and must re-authenticate before it can connect.

Source

Thrown at superset/commands/database/sync_permissions.py:121

        # Need user info to impersonate for OAuth2 connections. The id is
        # captured here, at validation/enqueue time, so that an async run of
        # this command binds to whoever held the username right now, rather
        # than re-resolving the (mutable) username at execution time.
        if not self.username or not (
            user := security_manager.get_user_by_username(self.username)
        ):
            raise UserNotFoundInSessionError()
        self._user_id = user.id

        with self.db_connection.get_sqla_engine() as engine:
            try:
                alive = ping(engine)
            except Exception as err:
                if (
                    self.db_connection.is_oauth2_enabled()
                    and self.db_connection.db_engine_spec.needs_oauth2(err)
                ):
                    raise MissingOAuth2TokenError() from err
                raise DatabaseConnectionFailedError() from err

        if not alive:
            raise DatabaseConnectionFailedError()

    def run(self) -> None:
        """
        Triggers the perm sync in sync or async mode.
        """
        self.validate()
        if self.async_mode:
            sync_database_permissions_task.delay(
                self.db_connection_id, self._user_id, self.old_db_connection_name
            )
            return

        self.sync_database_permissions()

View on GitHub (pinned to f4587218dd)

Solutions

  1. Re-authenticate via the OAuth2 flow (database connections UI -> authorize again) so a fresh token is issued
  2. Check the OAuth2 client credentials in the database connection settings and the driver config
  3. Inspect stored tokens/refresh errors in the logs for the underlying failure

Example fix

// before
 SyncPermissionsCommand(db_id, username).run()  # MissingOAuth2TokenError

// after
 # complete the OAuth2 authorize flow in the UI first, then:
 SyncPermissionsCommand(db_id, username).run()
Defensive patterns

Strategy: retry

Validate before calling

if db_conn.is_oauth2_enabled():
    # ensure an access token exists before syncing
    token = security_manager.get_oauth2_access_token(db_conn)
    if token is None:
        raise PermissionError("complete the OAuth2 authorize flow first")

Try / catch

try:
    cmd.run()
except MissingOAuth2TokenError:
    # send user through the OAuth2 authorize flow, then retry once
    ...

Prevention

When it happens

Trigger: Syncing permissions on an OAuth2-enabled database whose access token expired and no refresh token is stored; the OAuth2 token cache was cleared; the refresh flow was never completed for this user.

Common situations: Databricks (or similar) connections after token expiry; users who never went through the OAuth2 authorize flow; rotated client secrets invalidating refresh tokens.

Related errors


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