Your verification tool returns "risky" or "unknown" or "accept-all" on a chunk of your list, and gives you no guidance about what to do next.
That chunk is catch-all domains, and how you handle it determines whether your sending reputation survives the quarter. It is also the part of email verification where tool documentation is thinnest, which is strange given that it is where most of the real decisions live.
This is the complete picture: what catch-all actually is at the protocol level, why no verification service can resolve it, how much damage it does, and five practical strategies for handling it.
What a catch-all domain is
A catch-all domain is configured to accept mail addressed to any mailbox at that domain, whether or not the mailbox exists.
Send to [email protected] and it accepts. Send to [email protected] and it accepts that too. The receiving server is not making a claim that either mailbox exists. It is simply declining to make the distinction at the point where you asked.
What happens afterwards varies. Some servers route unmatched mail to an administrative mailbox. Some deliver it to a shared inbox nobody reads. Some accept it and discard it silently. And some accept it, then generate a bounce hours or days later once internal routing fails.
That last case is the expensive one, and the next sections explain why.
Why companies configure it
It is worth understanding the motivation, because it tells you something about which companies are catch-all and therefore where you will encounter the problem.
Nobody wants to lose mail to a typo. If a customer writes to [email protected], a catch-all configuration means that mail lands somewhere a human might see it rather than bouncing. For a business that cares about inbound, that is a reasonable tradeoff.
Mergers and reorganizations create address sprawl. After an acquisition, a company may hold several domains with overlapping and partially migrated mailboxes. Catch-all is the configuration that stops things disappearing during migration, and it very often never gets turned off afterwards.
It hides the directory. Rejecting unknown recipients tells an attacker exactly which mailboxes exist, which is useful for targeted phishing. Accepting everything reveals nothing. Several large mail platforms default to this behavior for precisely this reason.
Nobody ever revisited it. The most common reason. It was configured once by somebody who has left, and there has never been a reason to change it.
The practical consequence: catch-all correlates with larger, older, more acquisitive organizations. Which is to say, it concentrates in exactly the mid-market and enterprise accounts most B2B teams are trying to reach. This is not a problem that lives in the tail of your list.
Why verification cannot resolve it
To check whether a mailbox exists, a verification service begins a conversation with the receiving mail server and asks whether a given recipient is acceptable, without sending anything.
On a normal domain, the server answers honestly, and you get a usable verdict.
On a catch-all domain, the server accepts every recipient at that stage and defers the real decision to later, after a message has actually been delivered to it. There is no follow-up question available. The information you want does not exist at the point in the conversation where you are allowed to ask.
This is worth being blunt about: no verification provider can confirm an individual mailbox on a catch-all domain. Any vendor claiming otherwise is either guessing or redefining the word "verified." The honest behavior is to report the condition clearly and let you decide, which is why a dedicated catch_all flag matters more than a higher "valid" percentage.
1from renidly import Renidly
2
3renidly = Renidly() # reads RENIDLY_API_KEY from the environment
4
5check = renidly.emails.verify("[email protected]")
6
7print(check.deliverable) # True, but read the next line before acting on it
8print(check.catch_all) # True means the mailbox itself is unconfirmable
9print(check.reason) # catch_allIf your stack is Node, the same call with camelCase response fields:
1import { Renidly } from "renidly";
2
3const renidly = new Renidly();
4
5const check = await renidly.emails.verify("[email protected]");
6
7console.log(check.deliverable, check.catchAll, check.reason);The important detail is that deliverable and catch_all are separate fields, not one combined verdict. A catch-all address is genuinely deliverable in the sense that the server will accept it. It is simply not confirmed. Collapsing those two facts into a single boolean is how lists get built that look clean and are not.
Never branch on deliverable alone:
1if check.deliverable and not check.catch_all:
2 main_list.append(address) # confirmed
3elif check.catch_all:
4 catch_all_segment.append(address) # separate treatment, see below
5else:
6 suppress(address)The damage model
Here is why this specific condition causes more harm than ordinary bad data.
The feedback is delayed. A guessed or stale address on a normal domain bounces immediately, and you learn within minutes. On a catch-all domain the server accepts, so your sending tool records a successful delivery. The bounce, if it comes at all, arrives hours or days later through a different path, mixed into normal volume.
Attribution breaks. Because the bounce is detached in time from the send, your reporting rarely connects it back to the segment that caused it. You see your overall bounce rate creeping up over several weeks with no obvious cause.
The cost compounds past the bad addresses. Mailbox providers score sending domains on delivery outcomes. A rising bounce rate lowers that score, and a lower score means mail to good addresses starts landing in spam or being deferred. So the real cost is not the wasted sends to dead mailboxes, it is the suppressed delivery of mail that would otherwise have arrived.
Recovery is slow. Sender reputation degrades quickly and rebuilds slowly, over weeks of consistent good sending behavior. One aggressive campaign to an unsegmented list can cost you a quarter of deliverability.
This is the whole reason catch-all deserves its own handling rather than being rounded to "valid" or "invalid." It is the one condition where treating an uncertainty as a certainty has a delayed, compounding, hard-to-attribute cost.
Five strategies
In rough order of how much work they take.
1. Segment and send separately
The minimum viable approach, and the single highest-return change most teams can make.
Put catch-all addresses in their own list. Send to them on their own schedule, ideally from a separate subdomain, and monitor their bounce rate independently from your confirmed segment.
This does not improve your accuracy at all. What it does is contain the blast radius, so that when the catch-all segment underperforms, it does not drag your primary sending domain down with it. If you do one thing from this post, do this one.
2. Corroborate the person
This is where real accuracy improvement comes from.
A catch-all server will not tell you whether a mailbox exists. But you can ask a different question: does this address correspond to a real person who currently works at this company?
If reverse resolution returns a person with a matching name at that company, the address is very likely real. If it returns nothing, you are holding a guess at a domain that accepts guesses, which is the worst combination available.
1result = renidly.emails.reverse(address)
2
3if check.catch_all and result.found and result.confidence in ("high", "medium"):
4 likely_real.append(address) # corroborated
5elif check.catch_all:
6 low_confidence.append(address) # unconfirmed guess at an accepting domainThis converts a binary unknown into a graded signal, which is enough to make sending decisions on. You can spot-check a few addresses in the free reverse email lookup tool before building anything, and the full confidence model is in reverse email lookup.
3. Prefer found addresses over guessed ones
Where a catch-all address came from matters enormously, and most teams discard that information.
An address returned by a finder API that resolved an actual person is a different object from an address produced by applying first.last@ to a name. Both look identical in your database. On a normal domain the difference is revealed by verification. On a catch-all domain it never is, so provenance is the only signal you have left.
Store the source of every address. On catch-all domains, send to resolved addresses and hold back pattern-generated ones. The methods and their relative reliability are compared in how to find a work email address.
4. Confirm the person still works there
An address can be real, the domain can accept, and the person can have left in March.
On a confirmed domain this shows up as a bounce once the mailbox is deactivated. On a catch-all domain it never shows up at all. Mail is accepted indefinitely for someone who no longer works there, and you keep sending into a void with a clean-looking delivery rate.
This makes employment confirmation disproportionately valuable for catch-all addresses specifically. The movement patterns are in job change signals, and the free job change detector will check a single person if you want to see what that looks like.
5. Warm up and watch
For a large catch-all segment, send to a small sample first.
Take 200 addresses, send, and wait a full week before drawing conclusions, because the delay is the whole problem. If bounces come back under about 3%, the segment is behaving like a normal list and you can scale into it. If they come back at 10% or more, that segment needs the corroboration work in strategies 2 to 4 before it gets any more volume.
This costs you a week and tells you what the rest of the segment will do. Compared to discovering it across your whole list, it is extremely cheap.
Measure catch-all as its own metric
If you take catch-all seriously, your reporting has to reflect it. Four numbers, tracked separately from your main list:
| Metric | What it tells you |
|---|---|
| Catch-all share of list | How exposed you are overall |
| Catch-all bounce rate | Whether your corroboration is working |
| Corroboration rate | What share of catch-all addresses resolve to a real person |
| Reply rate, catch-all vs confirmed | The real business impact |
That last one is the one worth watching most. Bounce rate tells you about deliverability. Reply rate tells you whether anyone is actually reading mail sent to that segment, and a catch-all segment with a normal bounce rate and a near-zero reply rate is a segment landing in an unmonitored mailbox. Technically delivered, practically worthless, and invisible if you only track bounces.
For the broader framework on measuring provider output properly rather than trusting headline numbers, see how to evaluate a B2B data provider.
Doing this at list scale
For a real list, verification runs as a batch rather than per address:
1job = renidly.emails.verify_batch([r.email for r in rows])
2
3for row in job.stream():
4 persist(row.matched_input, row)1const job = await renidly.emails.verifyBatch(rows.map((r) => r.email));
2
3for await (const row of job.stream()) {
4 await persist(row.matched_input, row);
5}Streaming rather than waiting means a crash partway through does not discard completed work, and matched_input ties every result back to exactly what you submitted. The resumability patterns for larger jobs are in batch enrichment at scale.
Two cost notes. Every address checked is billed, including catch-all verdicts, because determining the condition takes the same work as any other check. And verification results have a shelf life measured in months, so cache the verdict with a timestamp rather than re-checking before every send. The field-level reasoning on refresh intervals is in CRM data decay, and current rates are on the pricing page.
Frequently asked questions
Is a catch-all email address valid?
The domain will accept mail for it, so it is deliverable in a technical sense. Whether the specific mailbox exists cannot be determined. Treat it as unconfirmed rather than valid or invalid.
Why does my verifier say "risky" or "accept-all"?
Those are names for the same condition. The receiving server accepted every recipient tested, so the tool cannot distinguish a real mailbox from one that does not exist.
What percentage of B2B domains are catch-all?
It varies by the list, and the share is consistently higher among larger and older organizations. Measure it on your own data rather than relying on a general figure, since your industry and company-size mix drive it almost entirely.
Can any tool verify a catch-all address?
No tool can confirm an individual mailbox on a catch-all domain, because the server does not expose that information. Anything claiming otherwise is inferring rather than verifying.
Should I delete catch-all addresses?
Usually not. They concentrate at the larger companies you most want to reach, so deleting them removes a meaningful share of your best accounts. Segment them and corroborate instead.
What bounce rate should I expect from a catch-all segment?
Higher than a confirmed segment. Under 3% after corroboration is reasonable; 10% or more means the segment needs work before it gets more volume.
Does catch-all affect my sender reputation?
Only through the bounces it produces. The condition itself is neutral. The risk is treating it as confirmed, sending at volume, and absorbing delayed bounces that suppress delivery of your good mail.
The one-line version
Catch-all means the server accepts everything, so the mailbox cannot be confirmed by anyone. Do not round it to valid. Segment it, send from a separate subdomain, corroborate addresses against whether a real person actually works there, favor resolved addresses over pattern-generated ones, and track its bounce and reply rates separately from your confirmed list.
The reason it matters more than the share of your list it occupies is that the feedback is delayed. By the time an unsegmented catch-all problem is visible in your reporting, it has already cost you delivery on mail that had nothing to do with it.
If you want to see what a real catch-all verdict looks like next to a confirmed mailbox, the free email verifier will check a single address with no signup. For programmatic use, the Email API returns catch_all as its own field alongside the deliverability verdict, and the Quickstart takes about five minutes.


