False positives: finding the customers you refused
A false positive is a legitimate request that filtering refused. Its defining property is not that it is wrong but that it is silent: the person affected sends no report, files no ticket, and leaves no entry that reads as a problem. Finding them is therefore something you do deliberately rather than something that happens to you.
What the refused person actually experiences
Picture it precisely: it explains the silence.
They do not see a security decision. They see a page that will not submit, a form that clears itself, an application that appears broken, or a refusal they have no vocabulary to describe. The conclusion available to them is that your site does not work, and the action available is to leave. Neither produces anything you can search for later.
The few who do report are a biased sample. They are the ones with an existing account, an order in progress, or a support contact they already know, which means the reports you receive describe the least severe version of the problem and come from the people least likely to be lost by it.
Where they hide in the record
Four places, in the order to check them.
Blocked requests that look like a visit. A person browsing arrives through a plausible sequence: a listing, a page, a form. A blocked request sitting in the middle of such a sequence, from an address that also produced successful requests, is a person and not a probe, whatever the URL it landed on suggests in isolation. This pattern is the single most reliable indicator available without additional data.
Blocks that cluster on one endpoint. Any form that legitimately carries awkward content will collide with content-inspecting rules: a bug report field carrying SQL, a support form carrying an HTTP error message, a comment field carrying HTML or quotes. The cluster is usually sharp, sitting on one path while the rest of the site shows nothing.
Blocks that cluster on one kind of client. Integrations, partner automation, and provider callbacks are legitimate machines, and they complain even less than people: they retry, exhaust their attempts, and fail into somebody else's log. A refused callback is often discovered as a business discrepancy weeks later rather than as a filtering event.
Divergence from what the business sees. A drop in completions for one form, in one country, or on one platform, without a matching change anywhere else, is worth checking against the record before it is explained as a seasonal effect. This is the check that finds what the first three miss.
How to size the problem
Carefully, and without inventing a percentage.
A false positive rate cannot be computed, because computing it would require knowing which of the refused requests were legitimate, which is the very thing you do not know. Any number presented as such is an estimate wearing a measurement's clothes, and it will be quoted later without its caveat.
What can be measured honestly is narrower and more useful:
Share by rule and by endpoint. Which rules account for most refusals, and which paths receive them. Concentration is the signal: a rule firing across the whole site behaves differently from one firing on a single form, and the second is far more likely to be a mismatch with your own content.
Trend after a change. Compare the same rule and endpoint before and after a configuration change. This measures your own edits rather than the truth of the world, and it is the only comparison where the denominator is stable.
Confirmed cases. The ones you established by investigation, counted as what they are: a floor rather than a rate. A handful of confirmed cases on one endpoint says more about that endpoint than any ratio would.
Fixing one without disabling everything
A ladder, narrowest rung first. Take the highest rung that solves the case in front of you and stop there.
Narrow by path. Adjust the behaviour for the specific route where the collision occurs, leaving every other route untouched. Most real cases end here, because most collisions are between one rule and one form.
Narrow by field or parameter. Where a single input carries the content that trips the rule, that input is the scope of the problem.
Narrow by client. Where the affected party is a known integration or callback, the exception describes that party rather than the path, which keeps the path protected for everybody else.
Change the rule's scope. Slower and more deliberate, appropriate when the same collision appears in several places for the same reason.
Before disabling a rule outright to unblock one form, note what that does: the rule stops applying everywhere, including the paths that were never involved and the ones that most needed it. This is the change that gets made under pressure at the end of a long day and is never revisited, and the time to write it down as a temporary measure is the moment you make it, rather than intending to remember.
Every narrowing above is an exception, and an exception without an owner and an end date is a permanent change that nobody decided to make. That subject has its own page in this section.
Not making the next one
Three habits, and the first does most of the work.
Watch before enforcing. A change observed first shows its collisions before they cost anything, which is what monitor mode is for and why it comes before enforcement rather than after a problem.
Change one thing at a time. Two adjustments made together produce a result that cannot be attributed to either, and the attribution is what you will need when a report arrives days later.
Keep a record of what changed and when. Reports about refused requests are always retrospective, and the question they raise is always the same: what was different that day. A short log of configuration changes answers it in seconds and is the cheapest thing on this page to maintain.
Questions
How do I know a blocked request was legitimate?
Look at what surrounds it. A refusal in the middle of an ordinary sequence of requests, from an address that also produced successful ones, is a person. A refusal standing alone, from an address with no other history, is not evidence of anything either way and is not worth investigating first.
What is an acceptable false positive rate?
The question has no answerable form, because the rate cannot be computed without knowing which refused requests were legitimate. Measure share by rule and endpoint, and the trend across your own changes, and treat confirmed cases as a floor rather than a percentage.
Should I disable the rule that keeps firing?
Not as a first step. Narrow it to the path, the field, or the client where the collision happens, which fixes the case without removing the rule from every other route. Disabling it outright is the change that survives longest and gets reviewed least.
Why do integrations never report being blocked?
Because they are built to retry rather than to complain. A refused callback exhausts its attempts and fails into somebody else's system, so the symptom surfaces as a business discrepancy later rather than as anything visible at the time it happens.
The cheapest false positive is the one found while nothing is being refused.
off
Nothing is inspected, and nothing is refused — including the collisions you have not found yet.
monitor
Collisions appear in the record before they cost anything. This is where the list is built.
block
Collisions become refusals. From here they are found by investigation, not by report.