What are Responders?
Responders determine how Caddy Defender handles requests from blocked IP ranges. Instead of simply blocking all unwanted traffic with a 403 error, you can choose from multiple response strategies to handle bots, scrapers, and AI crawlers in different ways. Every Defender configuration must specify exactly one responder type. The responder is triggered when a request originates from an IP address that matches your configured ranges and is not whitelisted.How Responders Work
When a request arrives, Caddy Defender:- Extracts the client IP from the request
- Checks if the IP is whitelisted (if so, allows the request)
- Checks if the IP matches any configured ranges
- If matched, invokes the configured responder
- If not matched, passes the request to the next handler
ServeHTTP method is called with full control over the response, allowing each responder type to implement its own behavior.
Available Responder Types
block
Returns a 403 Forbidden response with “Access denied” message. Simple and direct.
custom
Returns a customizable message with configurable status code. Useful for branded error pages.
drop
Immediately drops the connection without sending any response. Appears as a timeout to the client.
garbage
Returns random nonsensical data designed to pollute AI training datasets.
redirect
Redirects to a specified URL with a 308 Permanent Redirect.
ratelimit
Sets a header for rate limiting integration with other Caddy middleware.
tarpit
Streams data at an extremely slow rate to waste bot resources and time.
Responder Details
block - Simple HTTP 403 Response
block - Simple HTTP 403 Response
The block responder returns a standard HTTP 403 Forbidden status with a plain text “Access denied” message.Source Code: When to use:
responders/block.go:12-16- You want a straightforward block with standard HTTP semantics
- Logging and monitoring tools expect standard 403 responses
- You don’t need custom messaging
custom - Configurable Message and Status Code
custom - Configurable Message and Status Code
The custom responder allows you to return a specific message with a custom HTTP status code.Source Code: Configuration:
responders/custom.go:20-31message(required): Custom text to returnstatus_code(optional): HTTP status code (default: 200)
- You want to provide a branded or custom error message
- You need to return a specific status code
- You want to inform users why they’re blocked
- Caddyfile
- JSON
drop - Immediate Connection Termination
drop - Immediate Connection Termination
The drop responder immediately terminates the connection without sending any response.Source Code: When to use:
responders/drop.go:12-14This responder uses Go’s
http.ErrAbortHandler to forcefully close the connection. The client will see this as a connection timeout or reset.- You want to give no feedback to blocked clients
- You want to simulate server unavailability
- You want to minimize server resources spent on responses
garbage - Nonsensical Data Pollution
garbage - Nonsensical Data Pollution
The garbage responder returns randomly generated nonsensical text designed to be useless for AI training.Source Code: The garbage generator creates 100 lines of random characters, nonsense words, and unpredictable patterns:When to use:
responders/garbage.go:15-21- You want to actively pollute AI training datasets
- You want to provide a response but make it useless
- You’re dealing with aggressive AI scrapers
redirect - Permanent URL Redirection
redirect - Permanent URL Redirection
The redirect responder sends a 308 Permanent Redirect to a specified URL.Source Code: Configuration:
responders/redirect.go:14-17url(required): The destination URL for the redirect
- You want to redirect bots to a specific page (e.g., terms of service)
- You want to redirect to a honeypot or monitoring service
- You want to redirect AI crawlers to opt-out instructions
- Caddyfile
- JSON
Uses HTTP 308 (Permanent Redirect) instead of 301 to preserve the HTTP method.
ratelimit - Rate Limiting Integration
ratelimit - Rate Limiting Integration
The ratelimit responder sets a header that can be used by other Caddy middleware for rate limiting.Source Code: When to use:
responders/ratelimit.go:12-17Unlike other responders, the ratelimit responder continues the request chain by calling
next.ServeHTTP(). It marks the request for rate limiting but doesn’t block it directly.- You want to rate limit rather than completely block
- You’re integrating with Caddy rate limiting middleware
- You want gradual throttling instead of hard blocking
tarpit - Slow Data Streaming
tarpit - Slow Data Streaming
The tarpit responder streams data at an extremely slow rate to waste bot resources and time.Source Code: Additional Options:
responders/tarpit/tarpit.go:82-151The tarpit responder works by:- Opening a content reader (file, HTTP, or timeout-based)
- Detecting content type from the first 512 bytes
- Writing small chunks (configurable bytes per second) every 100ms
- Continuing until timeout or content exhausted
timeout
Duration before closing the connection
- Default:
30s - Example:
5m,1h
bytes_per_second
Rate of data streaming
- Default:
24 - Minimum:
10
response_code
HTTP status code
- Default:
200
content
Content source
- Format:
protocol://path - Protocols:
file,http,https - Optional (uses timeout reader if empty)
headers: Map of custom response headers
- You want to waste bot resources and slow them down
- You want to make scraping your site impractical
- You have high-quality content that aggressive bots are targeting
- Basic Timeout
- File Content
- HTTP Content
- JSON
Choosing the Right Responder
| Responder | Resource Usage | Stealth | AI Training Pollution | Best For |
|---|---|---|---|---|
block | Low | Low | None | Standard blocking |
custom | Low | Low | None | Branded error pages |
drop | Minimal | High | None | Silent blocking |
garbage | Low | Medium | High | Active AI poisoning |
redirect | Low | Low | None | Policy pages, honeypots |
ratelimit | Low | Low | None | Gradual throttling |
tarpit | High | Medium | Medium | Resource exhaustion |
Implementation Reference
All responders implement this interface fromresponders/responder.go:9-12:
config.go:171-200.