
Stop Chasing Ghost Hits
The fastest way to waste a weekend is to celebrate a Nuclei run with โhundreds of findingsโโฆ then watch 90% of them dissolve the moment you click through. Thatโs not paranoia. Thatโs single-signal matching, redirect sink pages, and WAF/CDN โhelpfulnessโ turning your scanner into a confetti cannon.
Nuclei template tuning is the practice of tightening how templates select targets and prove a match, using filters/tags, multi-signal matchers (status + headers + body), and negative matchers to exclude block pages, default shells, and other lookalikes. Done right, it raises truth density without blindly shrinking coverage.
Keep guessing and you lose time-to-triage, burn trust in your pipeline, and teach your team to ignore alerts.
This post gives you a repeatable system: scope smarter with tags and severity, build evidence stacks instead of vibes, add anti-evidence, and tame redirects, caching, and rate limits so โghost hitsโ stop haunting your dashboards.
The Lesson: I learned the hard way in CI: volume feels good for five minutes; precision pays all week.
Nuclei false positives usually come from overly broad matchers, missing negative conditions, and noisy targets. Start by scoping with tags and severities, then tighten matchers (status + headers + body patterns), add negative matchers, and validate against known-good/known-bad fixtures. Calibrate rate limits, retries, and redirect handling to avoid โghost hits.โ Finally, version your tuned set and measure precision over time.
Table of Contents

Who this is for / not for
For you ifโฆ
- You run Nuclei in CI/CD, scheduled scans, or client programs and triage is drowning you
- You maintain a private template pack (or fork community templates)
- You need repeatable precision (not โit worked once on my laptopโ)
Not for you ifโฆ
- Youโre looking for โscan everything everywhereโ defaults (that path leads to alert ash)
- You canโt validate findings against a second signal (logs, repro steps, manual check)
- Youโre running unauthorized scans (donโt)
- Discovery is allowed to be messy
- Confirmation must be stubbornly precise
- Every noisy template needs a home (quarantine or refactor)
Apply in 60 seconds: Pick one template you distrust and label it โdiscovery-onlyโ today.
Quick personal confession: the first time I ran Nuclei at scale in a pipeline, I celebrated the volumeโฆ then spent a weekend chasing โvulnsโ that were basically a CDNโs favorite error page wearing different hats. That weekend taught me an expensive lesson: high output isnโt the same as high signal.
Intent check: Why Nuclei โliesโ even when the template looks correct
False positive archetypes (so you can name the monster)
- Banner coincidences: generic strings matched on unrelated pages
- Redirect mirages: 301/302 chains landing on a default page that matches
- WAF reflections: blocked responses echoing payload fragments
- CDN edge sameness: shared error pages across hosts
- Cache ghosts: stale content reappearing under load
Hereโs the uncomfortable truth: Nuclei isnโt โlyingโ so much as itโs doing exactly what you told it to do. Itโs a very literal assistant. If your template says โif body contains Welcome then match,โ it will cheerfully agree with half the internet.
The quiet culprit: โsingle-signal matchingโ
Relying on only body text or only status codes is precision debt with interest. In real environments, a single clue is easy to fake by accident: SSO portals, shared UI components, reverse proxies, and WAFs all remix responses into something โclose enoughโ to trigger lazy matchers. If you want a broader mental model for where scanning sits in a real program (and why confirmation has different rules), compare penetration testing vs vulnerability scanning and notice how โdetectionโ and โvalidationโ live in different worlds.
Operator rule: A vulnerability match should feel like a lock clicking, not a coin landing somewhere on the table.
Another lived moment: I once watched a โcriticalโ finding disappear simply by changing the User-Agent. Same target. Same template. Different response shape. Thatโs not a vulnerability. Thatโs a transport artifact doing stand-up comedy.
Money Block: Eligibility checklist (are you ready to tune for precision?)
Answer Yes/No. If you hit 3+ โNo,โ fix that first or your tuning wonโt stick.
- Yes/No: You can reproduce a match with a second signal (curl, browser, logs, or a manual step)
- Yes/No: You can run a tiny โfixture scanโ (known-good + known-bad) on every template change
- Yes/No: Youโre separating discovery from confirmation in routing and alerting
- Yes/No: You control template versions (git tag, release notes, or a pinned commit)
- Yes/No: You can measure confirm rate weekly (even a simple spreadsheet counts)
Next step: If you answered โNoโ to fixtures, create two fixtures today before editing more regex.

Target scoping first: Tags, severity, and template selection that actually behaves
Build a โprecision-firstโ selection policy
- Prefer explicit tech tags (for example: apache, wordpress, jira) over broad categories
- Gate by severity plus confidence (an internal label is fine)
- Maintain allowlists for proven templates and quarantines for noisy ones
This is where most teams accidentally sabotage themselves: they treat template selection like a buffet. They pick โeverything that looks tasty,โ then wonder why the bill is triage fatigue. A clean selection policy becomes much easier when itโs aligned with an actual security testing strategy instead of โwhatever templates were trending this week.โ
Nuclei templates are YAML, and the community ecosystem moves fast. Thatโs great for coverage, but it means you should treat templates like dependencies: pin versions, review changes, and assume drift. ProjectDiscoveryโs tooling makes automation easy, which is exactly why you need policy, not vibes.
Curiosity gap: Which 10 templates cause 80% of your noise?
Do a 1-week audit: rank templates by hit count, then compare to confirmed findings. Youโll usually find a tiny set of โserial false-positive offenders.โ The fix is rarely heroic. Itโs usually selection + routing.
- Use tags to avoid scanning tech you donโt have
- Quarantine repeat offenders immediately
- Promote templates based on confirmation ratio
Apply in 60 seconds: Create two folders: allowlist and quarantine. Move one noisy template now.
Anecdote from a client engagement: we reduced triage volume by roughly โa whole engineer-day per weekโ by doing nothing fancy. We simply stopped running generic templates against a fleet of marketing landing pages. It wasnโt security. It was self-inflicted noise.
Show me the nerdy details
Selection policy works best when itโs reproducible: a pinned template commit, an explicit tag list, and a โpromotionโ rule (for example, must hit โฅ70% confirm rate over 20 samples before it can page). If you canโt enforce a percent, enforce a minimum sample size. Small numbers lie politely.
Matcher design: Stop trusting one clue, start building โevidence stacksโ
Use multi-signal matchers (minimum 2, ideally 3)
- Status (for example: 200/401/403)
- Headers (server/app fingerprints, auth challenges)
- Body (unique markers, not generic words)
Think of a good Nuclei matcher like a courtroom case. One witness is interesting. Three independent witnesses is convincing. Status alone is a mood. Body alone is poetry. Headers often carry the receipts. (If you want a founder-friendly lens on why โreceiptsโ matter, this pairs nicely with security metrics for founders, especially when youโre trying to defend precision work to non-security stakeholders.)
Prefer structure over vibes
- Anchor regex with context (boundaries, nearby tokens, predictable separators)
- Match stable identifiers (version strings, product paths, unique JSON keys)
- Require response โshapeโ when possible (Content-Type, JSON fields, HTML title patterns)
Pattern-interrupt micro (H3): Letโs be honestโฆ your regex is too romantic
If it matches on a blank page, it will match on the internet. And the internet has a lot of blank pages wearing costumes.
Personal scar tissue: I once inherited a template that matched on the word โerror.โ That was it. Just โerror.โ It flagged a payment processor outage page, a React build warning, and a printer manual. It also flagged exactly zero vulnerabilities. Points for ambition, minus points for reality.
Practical pattern: build an evidence stack (conceptual)
- Status: Require the expected class (for example, 401 when probing auth)
- Header: Require a specific challenge header or product header token
- Body: Match a product-unique string near a stable UI element or JSON key
- Anti-evidence: Exclude WAF block phrases and generic โnot foundโ shells
Neutral action: Add one extra independent signal to your noisiest matcher before you touch the regex.
Negative matching: The missing seatbelt that prevents โphantom vulnerabilitiesโ
Add โanti-evidenceโ conditions
- Exclude default error pages (404, โnot foundโ, generic app shells)
- Exclude WAF blocks (โaccess deniedโ, โincident idโ, โrequest blockedโ)
- Exclude login redirects where your payload never reached the endpoint
Negative matching is the part people skip because it feels pessimistic. But โpessimisticโ is just โaccurateโ in a world full of CDNs, WAFs, and helpful proxies. If youโre debating what โhelpfulโ security controls actually do at the edge, this idea clicks harder when youโve already mapped WAF vs RASP vs CSP for startups.
Use matchers-condition intentionally
- and for proof, or for discovery
- Discovery templates should be labeled and routed differently than vuln templates
One more lived moment: Iโve seen WAF block pages echo payload fragments back in the response body. The template โmatched,โ the tool reported success, and the finding looked real until you noticed the headers shouting โblocked.โ Thatโs not a vuln. Thatโs a bouncer repeating your name at the door.
- Block pages and default shells are predictable
- Redirect sinks can be detected
- Anti-evidence turns โmaybeโ into โnot this timeโ
Apply in 60 seconds: Add a single negative matcher for โaccess deniedโ or โrequest blockedโ to your noisiest template.
Show me the nerdy details
Negative matching is strongest when it targets response families, not single strings. WAFs (Cloudflare, Akamai, Fastly in front of apps, and many enterprise appliances) tend to include stable tokens: incident identifiers, โRay IDโ-style IDs, generic โblockedโ language, or standardized HTML shells. Build a small reusable negative-matcher snippet and apply it consistently.
Redirects, caching, and rate limits: The invisible settings that fabricate results
Redirect handling checklist
- Decide: follow redirects or not, per template type
- Detect โsink pagesโ (homepages, SSO portals) that create repeated matches
Redirects are where truth goes to get a costume change. If your scan follows redirects blindly, you may end up matching on the same SSO gateway across dozens of hosts and think you discovered a whole new universe. You didnโt. You discovered a hallway. And in SaaS environments, hallways often look like identity infrastructure, which is why it helps to understand SAML SSO for SaaS patterns when youโre diagnosing โwhy everything bounces to the same place.โ
Tune transport reality
- Rate limit to avoid CDN/WAF behavior changes under burst
- Retries and timeouts: too aggressive equals partial responses that still match
- Normalize headers/User-Agent to reduce variance between runs
A small confession: Iโve had โghost hitsโ appear only under load, then vanish when rechecked manually. The culprit wasnโt the application. It was the edge. Rate limiting and consistent request shaping turned the haunting into a predictable system.
Money Block: Decision card (follow redirects or not?)
Choose based on template purpose, not habit.
When to follow redirects
- Fingerprinting that expects canonical paths
- Well-known endpoints that legitimately redirect
- You also check for โsink pagesโ and anti-evidence
Time trade-off: More requests, more variability.
When not to follow redirects
- Vuln confirmation where the endpoint matters
- Targets that commonly bounce to SSO/home
- Youโve seen repeated matches across hosts
Time trade-off: Faster runs, fewer mirages.
Neutral action: Decide redirect policy for one template category today and document it.
Show me the nerdy details
Transport knobs change response shape. Under burst, CDNs may serve different cached variants; WAFs may switch from โmonitorโ to โchallengeโ; apps may return partial HTML shells. If your matchers donโt require stable headers or content-type, these variants become false positives. Treat rate limits, timeouts, and redirect policy as part of the templateโs detection logic.
Curiosity gap: Why โworks on one hostโ templates fail at scale
The scale trap
- Multi-tenant SaaS apps reuse UI fragments across customers
- CDNs share error content across origins
- Internationalization changes strings (your matcher breaks or over-matches)
When you test on one friendly host, everything looks crisp. At scale, you meet the real world: shared layouts, reused JavaScript bundles, and universal โsomething went wrongโ pages. Your matcher wasnโt wrong. It was under-specified.
The fix: test matrix thinking
Validate on at least: clean host, vulnerable host, WAF-protected host, redirected host. If you canโt get all four, get two: one known-good and one known-bad. Even that small contrast reveals where your matchers are bluffing.
Short Story: The Day the Homepage Became โCriticalโ (120โ180 words) โฆ
We were scanning a clientโs subdomains and celebrated a sudden spike in โhigh severityโ matches. The dashboard looked like fireworks. I did what every tired engineer does: I believed the dashboard for exactly thirty seconds. Then I clicked through. Every โfindingโ was the same destination: a glossy SSO portal that politely welcomed me, regardless of what I requested. Redirects were funneling everything into one sink page, and our body matcher was keying off a generic string that happened to appear in that portalโs HTML shell.
The fix was embarrassingly simple: stop following redirects for confirmation templates, require a product-specific header token, and add a negative matcher for the SSO page title. The fireworks stopped. The real findings remained. The team slept again.
Common mistakes that inflate false positives (and how to stop them)
Mistake #1: Matching on generic UI text
Replace โWelcomeโ, โDashboardโ, โSign inโ with product-unique markers. If your matcher would match a dozen unrelated login screens, itโs not a matcher. Itโs a horoscope.
Mistake #2: Ignoring content-type and response shape
- Require
application/jsonwhen expecting JSON - Require a specific HTML title pattern only when stable
Mistake #3: Treating discovery as exploitation confirmation
Split into two steps: detect โ confirm. Detection can be broader; confirmation must be stubborn. If your pipeline pages on detection, youโre paying interest on a loan you didnโt mean to take. This is also where your internal stakeholders will ask, โHow do we read this?โ so it helps to have a shared baseline for how to read a penetration test report and what counts as โconfirmedโ versus โsuspected.โ
Mistake #4: No baseline fixtures
Without known-good/known-bad fixtures, youโre tuning blindfolded. And the internet is not a gentle obstacle course.
- Reduce generic text matching
- Require response shape (content-type + structure)
- Separate detect vs confirm with different routing
Apply in 60 seconds: Add a content-type requirement to one JSON-based template.
Personal note: the first fixture set I built felt tedious. Two weeks later, it felt like a superpower. Every template change stopped being a gamble and became a controlled experiment.
Tuning workflow: A repeatable loop that doesnโt depend on heroics
Step 1: Label your templates by purpose
discovery,fingerprint,weak-auth,misconfig,vuln-confirm
Step 2: Add a โconfidence budgetโ to each template
- Low confidence โ requires manual confirmation
- High confidence โ allowed to page/alert
Step 3: Version and measure
- Track: hit rate, confirm rate, time-to-triage, top noisy templates
- Keep changelogs for matcher updates (future you will thank present you)
Pattern-interrupt micro (H3): Hereโs what no one tells youโฆ
The best tuning is mostly removing templates from the โauto-triageโ path, not perfecting every regex.
Lived experience: Iโve seen teams spend hours polishing a noisy discovery template when the correct move was to route it into a low-priority bucket. The result: fewer pages, fewer interruptions, and more time to confirm the things that mattered. Itโs the same energy as setting vulnerability remediation SLAs: you donโt โfix everything,โ you build a system that makes the right things inevitable.
Money Block: Mini calculator (template precision in 20 seconds)
Enter two numbers. No storage. No magic. Just a quick gut-check.
Neutral action: If precision is under 40%, demote the template before you debate regex aesthetics.
Curiosity gap: When false positives are actually โsignalโ youโre mis-scoping
If everything matches, your scope is the problem
- Are you scanning generic landing pages instead of app surfaces?
- Are you hitting the same SSO gateway across many hosts?
- Are you missing pre-filtering (tech fingerprint, port/service validation)?
Sometimes false positives are your system trying to whisper, โYouโre not looking at the app. Youโre looking at the lobby.โ If your target list includes lots of marketing pages, CDN-hosted static sites, or single sign-on gateways, broad templates will โmatchโ constantly because the responses are repetitive. This often intersects with โedge postureโ choices (and why the same block page shows up everywhere), which is where security headers ROI thinking can help you separate โapp truthโ from โedge performance theater.โ
Fix with โpre-conditionsโ
- Lightweight checks before expensive templates (ports, known paths, tech headers)
- Run fingerprint templates first, then only run tech-specific templates
Infographic: Precision-first flow (from scope to confirmation)
1) Pre-filter
Ports, known paths, basic tech hints
Output: smaller, cleaner target set
2) Fingerprint
Tech-specific templates only
Output: tag-driven routing
3) Confirm
Evidence stacks + negative matchers
Output: high-confidence findings
Accessibility note: This diagram shows a three-stage flow that reduces false positives by narrowing scope before confirmation.
Money Block: Quote-prep list (what to gather before comparing packs/policies)
- Your top 20 templates by hit count (last 7โ14 days)
- Confirm outcomes for each (true/false/unknown)
- Redirect behavior notes (sink pages, SSO gateways)
- WAF/CDN indicators seen in headers or bodies
- Your current rate limit, retries, timeouts, redirect policy
Neutral action: Collect this once, then tune based on data instead of arguments.

FAQ
1) How do I reduce Nuclei false positives without missing real findings?
Start with scope (tags, tech fingerprints, allowlists), then enforce evidence stacks (status + headers + body) and add negative matchers for block pages, default shells, and redirect sinks. Finally, validate on fixtures (known-good/known-bad) and measure confirm rate weekly so you donโt โtune blind.โ
2) Whatโs the best way to use tags and severity for safer CI scans?
In CI, prefer tech-specific tags and restrict to templates youโve promoted via confirmation ratio. Use severity as a gating layer, but donโt let โhigh severityโ auto-page unless the template is in your high-confidence set. CI is about regression and safety, not maximum coverage. If youโre building a program mindset across the org, pairing this with 1 hour a month security training can keep expectations sane: CI is a guardrail, not a prophecy.
3) Should I use and or or in matchers-condition for vulnerability templates?
Use and when youโre claiming a vulnerability and need proof. Reserve or for discovery and fingerprinting where broad coverage is acceptable, then route those results differently. A good rule: if it can page someone, it should require multiple independent signals.
4) How do I handle redirects so homepages donโt trigger matches?
Decide redirect policy per template purpose. For confirmation templates, consider not following redirects, or follow with strict sink-page detection (title/header markers) plus negative matchers. Also require a product-specific header or path marker so a generic homepage canโt impersonate the target endpoint.
5) Whatโs a good confirmation workflow for noisy discovery templates?
Treat discovery results as leads. Pipe them into a โneeds confirmationโ queue, then run a second-step confirmation template or a small manual checklist (curl + header checks + repro path). Promote templates only when they hit a stable confirm rate over a meaningful sample size.
6) Why do WAF block pages cause false positives and how do I exclude them?
Many WAFs reflect parts of your request or payload in the response body, which can accidentally satisfy body matchers. Exclude common block-page language and require headers/content-types consistent with the target application. When possible, add an explicit โnot blockedโ signal as anti-evidence. For teams formalizing this into policy, it can help to tie the โwhat we disclose and howโ thread back to a vulnerability disclosure policy so expectations stay aligned across engineering and security.
Conclusion
Remember the hook, that sinking feeling when your scan ends? Hereโs the loop closure: the cure is not โscan less.โ Itโs prove more. Most false positives come from two places: sloppy selection and single-signal matching. When you scope with tags, enforce evidence stacks, add negative matchers, and treat transport settings as part of detection logic, Nuclei stops sounding like an alarm and starts sounding like a trustworthy instrument.
If you do one thing in the next 15 minutes, do this: take your top noisy template, add one extra evidence signal and one negative matcher, then test against one known-good and one known-bad target. Ship it as tuned-pack v1.0 and measure confirm rate for 7 days. Precision loves a calendar. If your confirmation step routinely depends on reaching internal services via pivots, itโs worth being deliberate about your tunnel tooling choices, for example comparing Chisel vs Ligolo-NG and keeping a stable runbook like a Ligolo-NG setup guide so โtransport artifactsโ donโt sneak in through your own infrastructure.
Last reviewed: 2026-02