wpscanteam/wpscan · error · WPScan::Error::PluginsThresholdReached
The number of plugins detected reached the threshold of #{Pa
Error message
The number of plugins detected reached the threshold of #{ParsedCli.plugins_threshold} which might indicate False Positive. You can use --plugins-threshold to increase or disable this limit (set to 0 to disable), or use --exclude-content-based to ignore bad responses. What it means
Raised inside Plugins::KnownLocations#aggressive (app/finders/plugins/known_locations.rb:39) when the number of detected plugins reaches opts[:threshold] (default 100, from --plugins-threshold) during known-location brute force. Because valid_response_codes counts 200, 401, 403 and 500 as detections, a catch-all server answering every probed /wp-content/plugins/<slug>/ URL trips it — the threshold exists to abort obvious false-positive floods, and the raise happens mid-enumeration, aborting the scan.
Source
Thrown at app/finders/plugins/known_locations.rb:39
# outside the framework (e.g. directly from specs).
#
# @return [ Array<Plugin> ] Items appended this call (empty when
# already streamed into opts[:found] to avoid double-appending).
def aggressive(opts = {})
shared = opts[:found]
local = shared ? nil : []
count = 0
enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |res, slug|
finding_opts = opts.merge(found_by: found_by,
confidence: 80,
interesting_entries: ["#{res.effective_url}, status: #{res.code}"])
plugin = Model::Plugin.new(slug, target, finding_opts)
(shared || local) << plugin
count += 1
raise Error::PluginsThresholdReached if opts[:threshold].positive? && count >= opts[:threshold]
end
local || []
end
# @param [ Hash ] opts
# @option opts [ String ] :list
#
# @return [ Hash ]
def target_urls(opts = {})
slugs = opts[:list] || DB::Plugins.vulnerable_slugs
urls = {}
slugs.each do |slug|
urls[target.plugin_url(slug)] = slug
end
urlsView on GitHub (pinned to 62c9cef471)
Solutions
- Confirm the false-positive pattern: curl a random nonexistent plugin URL — if it returns 200, responses cannot be trusted
- Add --exclude-content-based '<regex>' to discard the bogus catch-all response bodies
- Raise or disable the guard when detections are real: --plugins-threshold 250 or --plugins-threshold 0
Example fix
# before wpscan --url http://t -e ap # => The number of plugins detected reached the threshold of 100 ... # after wpscan --url http://t -e ap --exclude-content-based 'nothing-found' # or, if detections are legit: --plugins-threshold 0
Defensive patterns
Strategy: fallback
Validate before calling
# Detect catch-all behavior before enumerating
random_slug = rand(36**12).to_s(36)
probe = Typhoeus.get("#{url}/wp-content/plugins/#{random_slug}/")
abort 'catch-all server: use --exclude-content-based or --plugins-threshold 0' if probe.code == 200 Type guard
# Threshold option guard: 0 disables the abort, positive enables it threshold_active = opts[:threshold].is_a?(Integer) && opts[:threshold].positive?
Try / catch
begin finder.aggressive(opts) rescue WPScan::Error::PluginsThresholdReached retry opts.merge(threshold: 0, exclude_content_based: pattern) # only after verifying detections are real end
Prevention
- Probe a random plugin slug URL first to detect catch-all 200 behavior
- Use --exclude-content-based on sites with soft-404 pages
- Tune --plugins-threshold for large multisite networks
- Never set --plugins-threshold 0 blindly on untrusted targets — verify detections manually
When it happens
Trigger: `wpscan --url http://t -e ap` where the target returns 200 (or 401/403/500) for nonexistent plugin paths — wildcard routing, custom error pages returning 200, a site-wide auth wall, or a genuinely huge install matching 100+ slugs from DB::Plugins.vulnerable_slugs with the default threshold of 100 left in place.
Common situations: Catch-all SPA routers serving index.html for any path; basic auth on the whole site (401 everywhere); misconfigured servers returning 500 globally; scanning large plugin-heavy networks with the default threshold.
Related errors
AI-assisted analysis of wpscanteam/wpscan@62c9cef471 (2026-08-21).
Data as JSON: /api/errors/f30a3c326f3d5326.
Report an issue: GitHub.