wpscanteam/wpscan · error · WPScan::Error::ConflictingApiTokens

--api-token and --enterprise-db-token are mutually exclusive

Error message

--api-token and --enterprise-db-token are mutually exclusive, please provide only one (this also applies to the WPSCAN_API_TOKEN and WPSCAN_ENTERPRISE_DB_TOKEN environment variables).

What it means

Raised by VulnApi.validate_api_tokens! (app/controllers/vuln_api.rb:26), invoked from Core#before_scan before any request is sent. It fires when both an API token and an enterprise DB token resolve at the same time — via --api-token/--enterprise-db-token flags, the WPSCAN_API_TOKEN/WPSCAN_ENTERPRISE_DB_TOKEN environment variables, or config files. The two tokens select mutually exclusive vulnerability-data backends (cloud API vs local enterprise dumps), so supplying both is rejected early.

Source

Thrown at app/controllers/vuln_api.rb:26

      ENTERPRISE_ENV_KEY = 'WPSCAN_ENTERPRISE_DB_TOKEN'

      # Class level so that Controller::Core (which runs first) can validate the tokens right after
      # the CLI options have been parsed, aborting before anything else (DB update, requests to the
      # target) is done.
      class << self
        # @return [ String, nil ] The enterprise DB token (CLI or ENV). Must match DB::Updater's resolution.
        def enterprise_db_token
          ParsedCli.enterprise_db_token || ENV.fetch(ENTERPRISE_ENV_KEY, nil)
        end

        # @return [ String, nil ] The API token (CLI or ENV var)
        def api_token
          ParsedCli.api_token || ENV.fetch(ENV_KEY, nil)
        end

        # @raise [ Error::ConflictingApiTokens ] When both the API and enterprise DB tokens are supplied
        def validate_api_tokens!
          raise Error::ConflictingApiTokens if enterprise_db_token && api_token
        end
      end

      def cli_options
        [
          OptString.new(
            ['--api-token TOKEN',
             'The WPScan API Token to display vulnerability data, available at https://wpscan.com/profile']
          ),
          OptString.new(
            ['--enterprise-db-token TOKEN',
             'Use a local enterprise vulnerability database dump instead of the WPScan API. The ' \
             'plugins/themes/wordpresses dumps are downloaded from enterprise-data.wpscan.org using ' \
             'this token during the database update, then read locally (no per-finding API calls). Mutually ' \
             "exclusive with --api-token. Can also be set via the #{ENTERPRISE_ENV_KEY} environment variable."],
            { advanced: true }
          ),
          OptBoolean.new(

View on GitHub (pinned to 62c9cef471)

Solutions

  1. Keep exactly one source: remove either --api-token or --enterprise-db-token from the command
  2. Check the environment: env | grep -i wpscan, then unset WPSCAN_API_TOKEN or unset WPSCAN_ENTERPRISE_DB_TOKEN
  3. Inspect config files (~/.config/wpscan/scan.{yml,json}, ./.wpscan/scan.{yml,json}) for api_token/enterprise_db_token keys and delete the extra one

Example fix

# before
WPSCAN_API_TOKEN=xxx wpscan --url http://t --enterprise-db-token yyy
# => --api-token and --enterprise-db-token are mutually exclusive ...

# after
unset WPSCAN_API_TOKEN
wpscan --url http://t --enterprise-db-token yyy
Defensive patterns

Strategy: validation

Validate before calling

# Assert token exclusivity before launching WPScan
api = ARGV.grep(/--api-token/) + [ENV['WPSCAN_API_TOKEN']].compact
ent = ARGV.grep(/--enterprise-db-token/) + [ENV['WPSCAN_ENTERPRISE_DB_TOKEN']].compact
abort 'pick exactly one token source' if api.any? && ent.any?
# or from Ruby: WPScan::Controller::VulnApi.validate_api_tokens!

Try / catch

begin
  WPScan::Controller::VulnApi.validate_api_tokens!
rescue WPScan::Error::ConflictingApiTokens
  ENV.delete('WPSCAN_API_TOKEN') # or drop the offending flag, then retry
  retry
end

Prevention

When it happens

Trigger: Any run where `ParsedCli.enterprise_db_token || ENV['WPSCAN_ENTERPRISE_DB_TOKEN']` and `ParsedCli.api_token || ENV['WPSCAN_API_TOKEN']` are both truthy — e.g. a CI pipeline exporting WPSCAN_API_TOKEN globally while the command also passes --enterprise-db-token.

Common situations: Shared CI runners carrying stale WPSCAN_* env vars; migration from the cloud API to the enterprise DB without unsetting the old variable; both keys present in ~/.config/wpscan/scan.yml plus an env var; copy-pasting an enterprise command into a shell that already exports WPSCAN_API_TOKEN.

Related errors


AI-assisted analysis of wpscanteam/wpscan@62c9cef471 (2026-08-21). Data as JSON: /api/errors/42bea0f4d9d976bc. Report an issue: GitHub.