Skip to content
GitHubXDiscord

EmailCatchAll

Configure a catch-all email routing rule that handles emails not matched by other routing rules. This rule is processed last and typically matches all unhandled emails.

Forward all unmatched emails to an admin address:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("default-catchall", {
zone: "example.com",
enabled: true,
actions: [
{
type: "forward",
value: ["admin@company.com"],
},
],
});

Configure catch-all to drop any emails that don’t match specific rules:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("drop-catchall", {
zone: "example.com",
enabled: true,
actions: [
{
type: "drop",
},
],
});

Use a Worker to handle all unmatched emails for custom processing:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("worker-catchall", {
zone: "example.com",
enabled: true,
name: "Worker processing",
actions: [
{
type: "worker",
value: ["email-processor"],
},
],
});

Send unmatched emails to multiple destinations:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("multi-forward-catchall", {
zone: "example.com",
enabled: true,
name: "Multi-destination catch-all",
actions: [
{
type: "forward",
value: ["admin@company.com", "backup@company.com"],
},
],
});

Perform multiple actions on unmatched emails:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("multi-action-catchall", {
zone: "example.com",
enabled: true,
name: "Forward and log all emails",
actions: [
{
type: "forward",
value: ["admin@company.com"],
},
{
type: "worker",
value: ["email-logger"],
},
],
});

Use custom matchers instead of the default “all” matcher:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("custom-catchall", {
zone: "example.com",
enabled: true,
name: "Custom catch-all",
matchers: [
{
type: "literal",
field: "to",
value: "*@example.com",
},
],
actions: [
{
type: "forward",
value: ["admin@company.com"],
},
],
});

Disable the catch-all rule when not needed:

import { EmailCatchAll } from "alchemy/cloudflare";
await EmailCatchAll("disabled-catchall", {
zone: "example.com",
enabled: false,
actions: [
{
type: "drop",
},
],
});

Reference an existing Zone resource:

import { EmailCatchAll, Zone } from "alchemy/cloudflare";
const zone = await Zone("my-zone", {
name: "example.com",
});
await EmailCatchAll("zone-ref-catchall", {
zone: zone,
enabled: true,
actions: [
{
type: "forward",
value: ["admin@company.com"],
},
],
});
  • zone (string | Zone): Zone ID or Zone resource where the catch-all rule will be configured
  • enabled (boolean, optional): Whether the catch-all rule is enabled. Defaults to true
  • name (string, optional): Name for the catch-all rule. Defaults to “Catch All”
  • matchers (EmailMatcher[], optional): Matchers for the catch-all rule. Defaults to [{ type: "all" }]
  • actions (EmailAction[]): Actions to take for emails that don’t match other rules
  • zoneId (string): Zone ID where the catch-all rule is configured
  • enabled (boolean): Whether the catch-all rule is enabled
  • name (string): Rule name
  • matchers (EmailMatcher[]): Matchers for the catch-all rule
  • actions (EmailAction[]): Actions for the catch-all rule
  • tag (string): Rule tag

The catch-all rule works differently from regular email rules:

  1. Last Priority: Catch-all rules are evaluated after all other routing rules
  2. Unmatched Emails: Only emails that don’t match any other rules reach the catch-all
  3. Single Rule: There can only be one catch-all rule per zone
  4. Special Endpoint: Uses a dedicated API endpoint (/catch_all) instead of regular rules

Forward unmatched emails to administrators:

await EmailCatchAll("admin-notification", {
zone: "example.com",
enabled: true,
name: "Admin notifications",
actions: [
{
type: "forward",
value: ["admin@company.com"],
},
],
});

Drop unmatched emails to prevent spam:

await EmailCatchAll("spam-prevention", {
zone: "example.com",
enabled: true,
name: "Drop unmatched emails",
actions: [
{
type: "drop",
},
],
});

Process unmatched emails with custom logic:

await EmailCatchAll("custom-processing", {
zone: "example.com",
enabled: true,
name: "Custom email processing",
actions: [
{
type: "worker",
value: ["unmatched-email-handler"],
},
],
});
  • Forward First: Start by forwarding unmatched emails to see what you’re getting
  • Analyze Patterns: Look for common patterns in unmatched emails
  • Refine Rules: Create specific rules for common patterns, then update catch-all
  • Monitor Volume: Watch for sudden increases in unmatched emails
  • Verify Destinations: Ensure catch-all destinations can handle the volume
  • Review Regularly: Periodically review what emails are being caught
  • Use Drop Wisely: Drop obvious spam/unwanted emails to reduce processing
  • Worker Efficiency: Keep Worker processing lightweight for high volumes
  • Multiple Destinations: Distribute load across multiple forwarding addresses

Forward unmatched emails to destination addresses:

{
type: "forward",
value: ["admin@company.com", "backup@company.com"]
}

Process unmatched emails with a Cloudflare Worker:

{
type: "worker",
value: ["unmatched-email-processor"]
}

Drop/reject unmatched emails:

{
type: "drop";
// No value needed
}
  • Only one catch-all rule per zone
  • Catch-all rules are evaluated last (after all other rules)
  • All limitations of regular email routing apply (destination verification, etc.)
  1. Check if Enabled: Verify the catch-all rule is enabled
  2. Other Rules Matching: Check if other rules are catching emails first
  3. Verify Destinations: Ensure forwarding addresses are verified
  1. Create Specific Rules: Add rules for common patterns to reduce catch-all volume
  2. Use Drop Action: Drop unwanted emails before they reach catch-all
  3. Monitor Patterns: Analyze unmatched emails to improve rule coverage
  1. Worker Logs: Check Worker script logs for processing errors
  2. Timeout Issues: Ensure Worker processing is fast enough for email volume
  3. Memory Limits: Monitor Worker memory usage for high-volume processing