{"record":{"id":"49ca1be34d4df66a","repo":"wpscanteam/wpscan","slug":"the-api-token-provided-is-invalid","errorCode":null,"errorMessage":"The API token provided is invalid","messagePattern":"The API token provided is invalid","errorType":"exception","errorClass":"WPScan::Error::InvalidApiToken","httpStatus":null,"severity":"error","filePath":"app/controllers/vuln_api.rb","lineNumber":66,"sourceCode":"             'Has no effect unless --proxy is also set.']\n          )\n        ]\n      end\n\n      def before_scan\n        # Already done by Core#before_scan (before the DB update, to fail as early as possible),\n        # kept as a safety net in case this controller is used in a chain without Core.\n        self.class.validate_api_tokens!\n\n        return setup_enterprise_db if enterprise_db_token\n\n        return unless api_token\n\n        DB::VulnApi.token = api_token\n\n        api_status = DB::VulnApi.status\n\n        raise Error::InvalidApiToken if api_status['status'] == 'forbidden'\n        raise Error::ApiLimitReached if api_status['requests_remaining'] == 0\n        raise Error::ApiConnectionError, api_status['http_error'] if api_status['http_error']\n      end\n\n      def after_scan\n        output('status', status: DB::VulnApi.status, api_requests: WPScan.api_requests)\n      end\n\n      private\n\n      # @return [ String, nil ] The enterprise DB token (CLI or ENV)\n      def enterprise_db_token\n        self.class.enterprise_db_token\n      end\n\n      # @return [ String, nil ] The API token (CLI or ENV var)\n      def api_token\n        self.class.api_token","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/wpscanteam/wpscan/blob/62c9cef471de90095f6b42245a11d0f8172d19c9/app/controllers/vuln_api.rb#L48-L84","documentation":"Raised by VulnApi#before_scan (app/controllers/vuln_api.rb:66) when the WPScan API answers the token status check with {'status' => 'forbidden'} after `DB::VulnApi.token = api_token`. The token was transmitted but rejected: wrong value, revoked/regenerated, or a different kind of token (e.g. an enterprise DB token pasted into --api-token).","triggerScenarios":"Running with --api-token TOKEN (or WPSCAN_API_TOKEN) whose value is wrong, truncated by shell quoting, carries trailing whitespace/newline from copy-paste, or was revoked on wpscan.com/profile; also when an enterprise DB token is mistakenly used with --api-token.","commonSituations":"Copy-paste errors (missing characters, stray spaces); token rotated on the website but stale in CI secrets; CI secret interpolation mangling the value; confusion between the API token and the enterprise DB token.","solutions":["Re-copy the token from https://wpscan.com/profile and re-run, minding quotes and whitespace","If set via env var, verify byte-exactness (e.g. echo -n \"$WPSCAN_API_TOKEN\" | wc -c against the expected length)","Make sure you are using the API token, not the enterprise DB token, with --api-token"],"exampleFix":"# before\nWPSCAN_API_TOKEN='xyz ' wpscan --url http://t   # trailing space from copy-paste\n# => The API token provided is invalid\n\n# after\nwpscan --url http://t --api-token xyz","handlingStrategy":"validation","validationCode":"# Validate the token with a status call before scanning\nWPScan::DB::VulnApi.token = candidate\nstatus = WPScan::DB::VulnApi.status\nabort 'bad token' if status['status'] == 'forbidden'","typeGuard":"# Guard on the status payload shape before branching\ninvalid = api_status.is_a?(Hash) && api_status['status'] == 'forbidden'","tryCatchPattern":"begin\n  scan.run\nrescue WPScan::Error::InvalidApiToken\n  abort 're-copy the token from wpscan.com/profile'\nend","preventionTips":["Store tokens in a secret manager; avoid inline quoting that can strip characters","Check token length/whitespace when copying between systems","Rotate CI secrets whenever the token is regenerated on the profile page","Never mix API tokens and enterprise DB tokens"],"tags":["api-token","authentication","forbidden","credentials"],"backgroundTag":"invalid-api-token","analyzedSha":"62c9cef471de90095f6b42245a11d0f8172d19c9","analyzedAt":"2026-08-21T17:10:47.902Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}