Tomcat provides two complementary request-processing extensibility mechanisms: Valves and Servlet Filters. Valves are Tomcat-native components configured inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/apache/tomcat/llms.txt
Use this file to discover all available pages before exploring further.
server.xml that operate at the container level (Server, Engine, Host, or Context). Filters are Jakarta EE standard components configured in web.xml that operate within a specific web application. Both form ordered processing chains applied to every incoming request.
Valve Pipeline
Each container (Engine, Host, Context) owns aPipeline consisting of an ordered list of Valve instances. A Valve receives the Request and Response, performs its logic, then calls getNext().invoke() to pass control down the chain. The last Valve in the chain calls the next container’s pipeline.
Configure Valves in server.xml inside the container element they should apply to:
server.xml
Built-in Valves
AccessLogValve
org.apache.catalina.valves.AccessLogValve — logs every HTTP request to a rotating log file.
pattern tokens:
| Token | Description |
|---|---|
%h | Remote host name (or IP if resolveHosts="false") |
%l | Remote logical username (always -) |
%u | Remote authenticated username |
%t | Date/time in Common Log Format |
%r | First line of the request (GET /path HTTP/1.1) |
%s | HTTP status code |
%b | Response size in bytes (- if zero) |
%D | Response time in milliseconds |
%T | Response time in seconds |
%I | Current request thread name |
%{X-Forwarded-For}i | Arbitrary request header value |
pattern="common" for Common Log Format or pattern="combined" for Combined Log Format.
JsonAccessLogValve
org.apache.catalina.valves.JsonAccessLogValve — emits access logs as JSON Lines, one JSON object per request. Ideal for log aggregation pipelines (ELK, Splunk, Datadog).
AccessLogValve patterns but serializes each field as a JSON key-value pair.
RemoteIpValve
org.apache.catalina.valves.RemoteIpValve — corrects the request.getRemoteAddr() and request.isSecure() values when Tomcat is behind a reverse proxy. Processes X-Forwarded-For and X-Forwarded-Proto headers.
StuckThreadDetectionValve
org.apache.catalina.valves.StuckThreadDetectionValve — detects threads that have been processing a request longer than a configured threshold and logs them (or optionally interrupts them).
| Attribute | Default | Description |
|---|---|---|
threshold | 600 | Seconds before a thread is considered stuck |
interruptThreadThreshold | -1 | Seconds before the stuck thread is interrupted; -1 disables |
HealthCheckValve
org.apache.catalina.valves.HealthCheckValve — returns HTTP 200 (server healthy) or 503 (server pausing/stopping) at a configurable path. Designed for load balancer health probes.
http://localhost:8080/health.
SemaphoreValve
org.apache.catalina.valves.SemaphoreValve — limits concurrent request processing using a semaphore. Requests exceeding the concurrency limit block or return an error immediately.
RewriteValve
org.apache.catalina.valves.rewrite.RewriteValve — mod_rewrite-style URL rewriting. Reads rules from a rewrite.config file.
rewrite.config in $CATALINA_BASE/conf/ (Host-level) or WEB-INF/ (Context-level). Example rules:
CrawlerSessionManagerValve
org.apache.catalina.valves.CrawlerSessionManagerValve — assigns search engine crawlers a single, shared session to prevent session proliferation.
ErrorReportValve / JsonErrorReportValve
org.apache.catalina.valves.ErrorReportValve — generates Tomcat’s default HTML error pages. Replace with JsonErrorReportValve to return JSON error responses (useful for REST APIs).
Built-in Servlet Filters
Configure Filters in your web application’sweb.xml (or via annotations):
CorsFilter
org.apache.catalina.filters.CorsFilter — implements the W3C CORS specification. Validates Origin headers and adds appropriate CORS response headers.
web.xml
| Init-param | Default | Description |
|---|---|---|
cors.allowed.origins | (empty — no origins allowed) | Comma-separated allowed origins; set to * to allow all |
cors.allowed.methods | GET,POST,HEAD,OPTIONS | Allowed HTTP methods |
cors.allowed.headers | Origin,Accept,... | Allowed request headers |
cors.exposed.headers | (empty) | Response headers exposed to the browser |
cors.support.credentials | false | Allow cookies/auth headers in cross-origin requests |
cors.preflight.maxage | 1800 | Pre-flight cache duration in seconds |
RateLimitFilter
org.apache.catalina.filters.RateLimitFilter — limits requests per IP address within a time window to mitigate DoS and brute-force attacks. Default: 300 requests per 60 seconds.
web.xml
CsrfPreventionFilter
org.apache.catalina.filters.CsrfPreventionFilter — implements the synchronizer token pattern to prevent Cross-Site Request Forgery attacks.
web.xml
RestCsrfPreventionFilter instead, which enforces CSRF protection via a custom request header.
HttpHeaderSecurityFilter
org.apache.catalina.filters.HttpHeaderSecurityFilter — adds multiple HTTP security response headers in a single filter.
web.xml
| Header added | Init-param | Default |
|---|---|---|
Strict-Transport-Security | hstsEnabled | true (only on HTTPS) |
X-Frame-Options | antiClickJackingEnabled | true (DENY) |
X-Content-Type-Options: nosniff | blockContentTypeSniffingEnabled | true |
Writing a Custom Valve
ExtendValveBase and override invoke():
MyLoggingValve.java
server.xml:
Clustering
Use ClusterValve with SimpleTcpCluster for session replication.
Security Realms
Configure Realm-based authentication that Valves and Filters can integrate with.
