Standard Modules

Module alpn

The alpn module enables support for the ALPN negotiation mechanism of the TLS protocol.

You can configure the list of application protocols negotiated by the ALPN mechanism, as well as the default protocol to use if the ALPN negotiation fails (for example, the client does not support ALPN).

The module properties are:

## Specifies the ordered list of application protocols supported by the server.
## The default list is specified by the list of the protocol modules that have
## been enabled, and the order is specified by the module dependencies.
# jetty.alpn.protocols=h2,http/1.1

## Specifies the protocol to use when the ALPN negotiation fails.
# jetty.alpn.defaultProtocol=http/1.1

Module bytebufferpool

The bytebufferpool module allows you to configure the server-wide ByteBuffer pool. Pooling ByteBuffers results in less memory usage and less pressure on the Garbage Collector.

ByteBuffers are pooled in buckets; each bucket as a capacity that is a multiple of a capacity factor that you can configure. For example, if a request for a ByteBuffer of capacity 2000 is requested, and the capacity factor is 1024, then the pool will allocate a buffer from the second bucket, of capacity 2048 (1024 * 2).

Applications that need to sustain many concurrent requests — or load spikes — may require many buffers during peak load. These buffers will remain pooled once the system transitions to a lighter load (or becomes idle), and it may be undesirable to retain a lot of memory for an idle system.

It is possible to configure the max heap memory and the max direct memory that the pool retains. Excess buffers will not be pooled and will be eventually garbage collected.

The module file is $JETTY_HOME/modules/bytebufferpool.mod:

[description]
Configures the ByteBufferPool used by ServerConnectors.
The bucket sizes increase linearly.
Use module "bytebufferpool-quadratic" for a pool that holds more coarse sized buffers.

[depends]
logging

[xml]
etc/jetty-bytebufferpool.xml

[ini-template]
## Minimum capacity of a single ByteBuffer.
#jetty.byteBufferPool.minCapacity=0

## Maximum capacity of a single ByteBuffer.
## Requests for ByteBuffers larger than this value results
## in the ByteBuffer being allocated but not pooled.
#jetty.byteBufferPool.maxCapacity=65536

## Bucket capacity factor.
## ByteBuffers are allocated out of buckets that have
## a capacity that is multiple of this factor.
#jetty.byteBufferPool.factor=4096

## Maximum size for each bucket (-1 for unbounded).
#jetty.byteBufferPool.maxBucketSize=-1

## Maximum heap memory held idle by the pool (0 for heuristic, -1 for unlimited).
#jetty.byteBufferPool.maxHeapMemory=0

## Maximum direct memory held idle by the pool (0 for heuristic, -1 for unlimited).
#jetty.byteBufferPool.maxDirectMemory=0

## Whether statistics are enabled.
#jetty.byteBufferPool.statisticsEnabled=false

Among the configurable properties, the most relevant are:

jetty.byteBufferPool.maxHeapMemory

This property allows you to cap the max heap memory retained by the pool.

jetty.byteBufferPool.maxDirectMemory

This property allows you to cap the max direct memory retained by the pool.

Module connectionlimit

The connectionlimit module limits the number of connections accepted by the server, across all connectors.

Once the configured maximum number of connections is reached, Jetty will not accept more connections. Existing, established connections will work normally. When existing connections are closed, accepting new connections will be resumed.

The number of connections seen at the JVM level may be different from the number of connections seen at the OS level. For more information, refer to this section.

The module file is $JETTY_HOME/modules/connectionlimit.mod:

The maximum number of TCP connections allowed across all connectors.

#jetty.connectionlimit.maxConnections=1000

The idle timeout to apply (in milliseconds) to existing connections when the connection limit is reached.

#jetty.connectionlimit.idleTimeout=1000

Module console-capture

The console-capture module captures System.out and System.err output and appends it to a rolling file.

The file is rolled every day at the midnight of the configured timezone. Old, rolled files are kept for the number of days specified by the jetty.console-capture.retainDays property.

The module properties are:

## Logging directory (relative to $JETTY_BASE).
# jetty.console-capture.dir=./logs

## Whether to append to existing file.
# jetty.console-capture.append=true

## How many days to retain old log files.
# jetty.console-capture.retainDays=90

## Timezone ID of the log timestamps, as specified by java.time.ZoneId.
# jetty.console-capture.timezone=GMT

Module core-deploy

This module enables webapp deployment from the $JETTY_BASE/webapps directory.

Deployment is managed via a DeploymentManager component that watches a directory for changes. See how to deploy web applications for more information.

TODO

Module cross-origin

The cross-origin module provides support for the CORS protocol implemented by browsers when performing cross-origin requests.

This module installs the CrossOriginHandler in the Handler tree; CrossOriginHandler inspects cross-origin requests and adds the relevant CORS response headers.

CrossOriginHandler should be used when an application performs cross-origin requests to your domain, to protect from cross-site request forgery attacks.

The module properties are:

## Whether cross-origin requests can include credentials such as cookies or authentication headers.
# jetty.crossorigin.allowCredentials=false

## A comma-separated list of headers allowed in cross-origin requests.
# jetty.crossorigin.allowedHeaders=Content-Type

## A comma-separated list of HTTP methods allowed in cross-origin requests.
# jetty.crossorigin.allowedMethods=GET,POST,HEAD

## A comma-separated list of origins regex patterns allowed in cross-origin requests.
# jetty.crossorigin.allowedOriginPatterns=

## A comma-separated list of timing origins regex patterns allowed in cross-origin requests.
# jetty.crossorigin.allowedTimingOriginPatterns=

## Whether preflight requests are delivered to the child Handler of CrossOriginHandler.
# jetty.crossorigin.deliverPreflightRequests=false

## Whether requests whose origin is not allowed are delivered to the child Handler of CrossOriginHandler.
# jetty.crossorigin.deliverNonAllowedOriginRequests=true

## Whether WebSocket upgrade requests whose origin is not allowed are delivered to the child Handler of CrossOriginHandler.
# jetty.crossorigin.deliverNonAllowedOriginWebSocketUpgradeRequests=false

## A comma-separated list of headers allowed in cross-origin responses.
# jetty.crossorigin.exposedHeaders=

## How long the preflight results can be cached by browsers, in seconds.
# jetty.crossorigin.preflightMaxAge=60

Module debuglog

The debuglog module logs extra information about request processing.

This module installs the DebugHandler into the handler tree and logs information into a rollover log file. By default, the location of the log file is $JETTY_BASE/logs, although this can be configured via the jetty.debuglog.dir. The name of the log file is of the form: yyyy_mm_dd.debug.log, for example 2024-10-01.debug.log. All deployed contexts will write to the same log file.

Note that if a request uses asynchronous processing, the log event for the completion of handling may occur out of order with the log event for the continuation of processing.

If more precise logging of request processing is required - including well-ordered async processing events - or you wish to constrain request debug logging to particular contexts only, then configure an ee-specific DebugListener for each context instead of using this module.

The module properties are:

## Logging directory (relative to $jetty.base)
# jetty.debuglog.dir=logs

## Whether to append to existing file
# jetty.debuglog.append=false

## How many days to retain old log files
# jetty.debuglog.retainDays=90

## Timezone of the log entries
# jetty.debuglog.timezone=GMT

## Show Request/Response headers
# jetty.debug.showHeaders=true

Module ee{8,9,10}-deploy

This module enables webapp deployment from the $JETTY_BASE/webapps directory.

Deployment is managed via a DeploymentManager component that watches a directory for changes. See how to deploy web applications for more information.

Adding files or directories to this monitored directory will cause the DeploymentManager to deploy them as web applications; updating files already existing in this monitored directory will cause the DeploymentManager to re-deploy the corresponding web application; removing files in this monitored directory will cause the DeploymentManager to "undeploy" the corresponding web application. (You can find a more detailed discussion of these rules in the deployment rules section.)

Multiple versions of this module exist (ee{8,9,10}-deploy) to support each Jakarta EE platform’s version of the Java Servlet specification. Jetty’s configuration properties are nearly identical across these versions; the configuration properties for the ee10-deploy Jetty module are:

## Monitored directory name (relative to $jetty.base)
# jetty.deploy.monitoredDir=webapps

## Defaults Descriptor for all deployed webapps
# jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault-ee10.xml

## Monitored directory scan period (seconds)
# jetty.deploy.scanInterval=0

## Whether to extract *.war files
# jetty.deploy.extractWars=true

## Whether to give the parent classloader priority
# jetty.deploy.parentLoaderPriority=true

## Comma separated list of configuration classes to set.
# jetty.deploy.configurationClasses=

## Pattern to select jars from the container classloader to be scanned (or null to scan no jars)
# jetty.deploy.containerScanJarPattern=.*/jakarta.servlet-api-[^/]*\.jar$|.*jakarta.servlet.jsp.jstl-.*\.jar$

## Pattern to select jars from the container classloader to be scanned (or null to scan all jars).
# jetty.deploy.webInfScanJarPattern=

## Pattern to exclude discovered ServletContainerInitializers
# jetty.deploy.servletContainerInitializerExclusionPattern=

## Order of discovered ServletContainerInitializers
# jetty.deploy.servletContainerInitializerOrder=

Among the configurable properties, the most relevant are:

jetty.deploy.monitoredDir

The name of the monitored directory.

jetty.deploy.scanInterval

The scan period in seconds, that is how frequently the DeploymentManager wakes up to scan the monitored directory for changes. Setting jetty.deploy.scanInterval=0 disabled hot deployment so that only static deployment will be possible (see also here for more information).

Module ee{8,9,10}-webapp

This module enables deployment of Java Servlet web applications.

Multiple versions of this module exist (ee{8,9,10}-webapp) to support each Jakarta EE platform’s version of the Java Servlet specification. Jetty’s configuration properties are identical across all versions of this module, and are as follows:

## Add to the environment wide default jars and packages protected or hidden from webapps.
## Protected (aka System) classes cannot be overridden by a webapp.
## Hidden (aka Server) classes cannot be seen by a webapp
## Lists of patterns are comma separated and may be either:
##  + a qualified classname e.g. 'com.acme.Foo' 
##  + a package name e.g. 'net.example.'
##  + a jar file e.g. '${jetty.base.uri}/lib/dependency.jar' 
##  + a directory of jars,resource or classes e.g. '${jetty.base.uri}/resources' 
##  + A pattern preceded with a '-' is an exclusion, all other patterns are inclusions
##
## The +=, operator appends to a CSV list with a comma as needed.
##
#jetty.webapp.addProtectedClasses+=,org.example.
#jetty.webapp.addHiddenClasses+=,org.example.

Module http

The http module provides the clear-text connector and support for the clear-text HTTP/1.1 protocol, and depends on the server module.

The module properties to configure the clear-text connector are:

### Clear-Text HTTP Connector Configuration

## The host/address to bind the connector to.
# jetty.http.host=0.0.0.0

## The port the connector listens on.
# jetty.http.port=8080

## The connector idle timeout, in milliseconds.
# jetty.http.idleTimeout=30000

## The number of acceptors (-1 picks a default value based on number of cores).
# jetty.http.acceptors=1

## The number of selectors (-1 picks a default value based on number of cores).
# jetty.http.selectors=-1

## The ServerSocketChannel accept queue backlog (0 picks the platform default).
# jetty.http.acceptQueueSize=0

## The thread priority delta to give to acceptor threads.
# jetty.http.acceptorPriorityDelta=0

## Whether to enable the SO_REUSEADDR socket option.
# jetty.http.reuseAddress=true

## Whether to enable the SO_REUSEPORT socket option.
# jetty.http.reusePort=false

## Whether to enable the TCP_NODELAY socket option on accepted sockets.
# jetty.http.acceptedTcpNoDelay=true

## The SO_RCVBUF socket option to set on accepted sockets.
## A value of -1 indicates that the platform default is used.
# jetty.http.acceptedReceiveBufferSize=-1

## The SO_SNDBUF socket option to set on accepted sockets.
## A value of -1 indicates that the platform default is used.
# jetty.http.acceptedSendBufferSize=-1

Among the configurable properties, the most relevant are:

jetty.http.port

The network port that Jetty listens to for clear-text HTTP/1.1 connections — default 8080.

jetty.http.idleTimeout

The amount of time a connection can be idle (i.e. no bytes received and no bytes sent) until the server decides to close it to save resources — default 30 seconds.

jetty.http.acceptors

The number of threads that compete to accept connections — default 1. Use -1 to let the accept heuristic decides the value; the current heuristic calculates a value based on the number of cores). Refer to this section for more information about acceptor threads.

jetty.http.selectors

The number of NIO selectors (with an associated thread) that manage connections — default -1 (i.e. a select heuristic decides the value; the current heuristic calculates a value based on the number of cores).

Configuration of Acceptors

Accepting connections from remote clients may be configured as a blocking operation, or a non-blocking operation.

When accepting connections is configured as a blocking operation (the number of acceptors is greater than zero), a thread is blocked in the accept() call until a connection is accepted, and other acceptor threads (if any) are blocked on the lock acquired by the accepting thread just before the accept() call.

When the accepting thread accepts a connection, it performs a little processing of the just accepted connection, before forwarding it to other components.

During this little processing other connections may be established; if there is only one accepting thread, the newly established connections are waiting for the accepting thread to finish the processing of the previously accepted connection and call again accept().

Servers that manage a very high number of connections that may (naturally) come and go, or that handle inefficient protocols that open and close connections very frequently (such as HTTP/1.0) may benefit of an increased number of acceptor threads, so that when one acceptor thread processes a just accepted connection, another acceptor thread can immediately take over accepting connections.

When accepting connections is configured as a non-blocking operation (the number of acceptors is zero), then the server socket is set in non-blocking mode and added to a NIO selector. In this way, no dedicated acceptor threads exist: the work of accepting connections is performed by the selector thread.

Configuration of Selectors

Performing a NIO select() call is a blocking operation, where the selecting thread is blocked in the select() call until at least one connection is ready to be processed for an I/O operation. There are 4 I/O operations: ready to be accepted, ready to be connected, ready to be read and ready to be written.

A single NIO selector can manage thousands of connections, with the assumption that not many of them will be ready at the same time.

For a single NIO selector, the ratio between the average number of selected connections over the total number of connections for every select() call depends heavily on the protocol but also on the application.

Multiplexed TCP protocols such as HTTP/2 tend to be busier than duplex protocols such as HTTP/1.1, leading to a higher ratio.

REST applications that exchange many little JSON messages tend to be busier than file server applications, leading to a higher ratio.

The higher the ratio, the higher the number of selectors you want to have, compatibly with the number of cores — there is no point in having 64 selector threads on a single core hardware.

Module http2

The http2 module enables support for the secure HTTP/2 protocol.

The module properties are:

## Specifies the maximum number of concurrent requests per session.
# jetty.http2.maxConcurrentStreams=128

## Specifies the initial stream receive window (client to server) in bytes.
# jetty.http2.initialStreamRecvWindow=524288

## Specifies the initial session receive window (client to server) in bytes.
# jetty.http2.initialSessionRecvWindow=1048576

## Specifies the maximum number of keys in all SETTINGS frames received by a session.
# jetty.http2.maxSettingsKeys=64

## Specifies the maximum number of bad frames and pings per second,
## after which a session is closed to avoid denial of service attacks.
# jetty.http2.rateControl.maxEventsPerSecond=50

The jetty.http2.rateControl.maxEventsPerSecond property controls the number of "bad" or "unnecessary" frames that a client may send before the server closes the connection (with code ENHANCE_YOUR_CALM) to avoid a denial of service.

For example, an attacker may send empty SETTINGS frames to a server in a tight loop. While the SETTINGS frames don’t change the server configuration and each of them is somehow harmless, the server will be very busy processing them because they are sent by the attacker one after the other, causing a CPU spike and eventually a denial of service (as all CPUs will be busy processing empty SETTINGS frames).

The same attack may be performed with PRIORITY frames, empty DATA frames, PING frames, etc.

Module http2c

The http2c module enables support for the clear-text HTTP/2 protocol.

The module properties are:

## Specifies the maximum number of concurrent requests per session.
# jetty.http2c.maxConcurrentStreams=128

## Specifies the initial stream receive window (client to server) in bytes.
# jetty.http2c.initialStreamRecvWindow=524288

## Specifies the initial session receive window (client to server) in bytes.
# jetty.http2c.initialSessionRecvWindow=1232896

## Specifies the maximum number of keys in all SETTINGS frames received by a session.
# jetty.http2c.maxSettingsKeys=64

## Specifies the maximum number of bad frames and pings per second,
## after which a session is closed to avoid denial of service attacks.
# jetty.http2c.rateControl.maxEventsPerSecond=50

The jetty.http2.rateControl.maxEventsPerSecond property controls the number of "bad" or "unnecessary" frames that a client may send before the server closes the connection (with code ENHANCE_YOUR_CALM) to avoid a denial of service.

For example, an attacker may send empty SETTINGS frames to a server in a tight loop. While the SETTINGS frames don’t change the server configuration and each of them is somehow harmless, the server will be very busy processing them because they are sent by the attacker one after the other, causing a CPU spike and eventually a denial of service (as all CPUs will be busy processing empty SETTINGS frames).

The same attack may be performed with PRIORITY frames, empty DATA frames, PING frames, etc.

Module http3

The http3 module enables support for the HTTP/3 protocol.

The module properties are:

## The host/address to bind the connector to.
# jetty.quic.host=0.0.0.0

## The port the connector listens on.
# jetty.quic.port=8444

## The connector idle timeout, in milliseconds.
# jetty.quic.idleTimeout=30000

## Specifies the maximum number of concurrent requests per session.
# jetty.quic.maxBidirectionalRemoteStreams=128

## Specifies the session receive window (client to server) in bytes.
# jetty.quic.sessionRecvWindow=4194304

## Specifies the stream receive window (client to server) in bytes.
# jetty.quic.bidirectionalStreamRecvWindow=2097152

## Specifies the stream idle timeout, in milliseconds.
# jetty.http3.streamIdleTimeout=30000

Module http-forwarded

The http-forwarded module provides support for processing the Forwarded HTTP header (defined in RFC 7239) and the now obsoleted X-Forwarded-* HTTP headers.

The module properties are:

### ForwardedRequestCustomizer Configuration

## Whether to process only the RFC7239 "Forwarded" header.
## "X-Forwarded-*" headers are not processed.
# jetty.httpConfig.forwardedOnly=false

## Whether the address obtained from "Forwarded: by=" or
## "X-Forwarded-Server" is used in the request authority.
# jetty.httpConfig.forwardedProxyAsAuthority=false

## Whether the "X-Forwarded-Port" header is used in the request authority,
## or else it is the remote client port.
# jetty.httpConfig.forwardedPortAsAuthority=true

## The name of the RFC 7239 HTTP header.
# jetty.httpConfig.forwardedHeader=Forwarded

## The name of the obsolete forwarded host HTTP header.
# jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host

## The name of the obsolete forwarded server HTTP header.
# jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server

## The name of the obsolete forwarded scheme HTTP header.
# jetty.httpConfig.forwardedProtoHeader=X-Forwarded-Proto

## The name of the obsolete forwarded for HTTP header.
# jetty.httpConfig.forwardedForHeader=X-Forwarded-For

## The name of the obsolete forwarded port HTTP header.
# jetty.httpConfig.forwardedPortHeader=X-Forwarded-Port

## The name of the obsolete forwarded https HTTP header.
# jetty.httpConfig.forwardedHttpsHeader=X-Proxied-Https

## The name of the obsolete forwarded SSL session ID HTTP header.
# jetty.httpConfig.forwardedSslSessionIdHeader=Proxy-ssl-id

## The name of the obsolete forwarded SSL cipher HTTP header.
# jetty.httpConfig.forwardedCipherSuiteHeader=Proxy-auth-cert

Module https

The https module provides the HTTP/1.1 protocol to the ssl module.

The module file is $JETTY_HOME/modules/https.mod:

# DO NOT EDIT THIS FILE - See: https://jetty.org/docs/

[description]
Adds HTTPS protocol support to the TLS(SSL) Connector.

[tags]
connector
https
http
ssl

[depend]
ssl

[after]
alpn
http2
http-forwarded

[xml]
etc/jetty-https.xml

Module jmx

This module enables deployment of Java Servlet web applications.

This configuration is useful for local development and testing. If you need to enable remote access, use the jmx-remote module.

Module jmx-remote

The jmx-remote module provides remote access to JMX clients.

The module properties to configure remote JMX connector are:

## The host/address to bind the RMI server to.
# jetty.jmxremote.rmiserverhost=localhost

## The port the RMI server listens to (0 means a random port is chosen).
# jetty.jmxremote.rmiserverport=1099

## The host/address to bind the RMI registry to.
# jetty.jmxremote.rmiregistryhost=localhost

## The port the RMI registry listens to.
# jetty.jmxremote.rmiregistryport=1099

## The host name exported in the RMI stub.
-Djava.rmi.server.hostname=localhost

The system property java.rmi.server.hostname is specified with the usual notation, prepending a -D in front of the system property name.

The system property java.rmi.server.hostname is uncommented because it is necessary in the default configuration — most systems do not have the local name resolution configured properly for remote access.

As an example, in a Linux machine named beryl, the /etc/hosts file may contain these entries:

127.0.0.1 localhost
127.0.1.1 beryl

If the system property java.rmi.server.hostname is not specified, the RMI implementation uses the host name beryl to figure out the IP address to store in the RMI stub, in this case 127.0.1.1. However, we the RMI server is configured to bind to localhost, i.e. 127.0.0.1.

If the system property java.rmi.server.hostname is not specified, the RMI client will try to connect to 127.0.1.1 (because that’s what in the RMI stub) and fail because nothing is listening on that address.

Module requestlog

The requestlog module provides HTTP request/response logging in the standard NCSA format, or in a custom format of your choice.

The module properties are:

## Format string
# jetty.requestlog.formatString=%{client}a - %u %{dd/MMM/yyyy:HH:mm:ss ZZZ|GMT}t "%r" %s %O "%{Referer}i" "%{User-Agent}i"

## Logging directory (relative to $jetty.base)
# jetty.requestlog.dir=logs

## File path
# jetty.requestlog.filePath=${jetty.requestlog.dir}/yyyy_mm_dd.request.log

## Date format for rollovered files (uses SimpleDateFormat syntax)
# jetty.requestlog.filenameDateFormat=yyyy_MM_dd

## How many days to retain old log files
# jetty.requestlog.retainDays=90

## Whether to append to existing file
# jetty.requestlog.append=false

## Timezone of the log file rollover
# jetty.requestlog.timezone=GMT

The property jetty.requestlog.formatString can be customized using format codes.

Format codes are specified with the syntax %MODIFIERS{PARAM}CODE as follows:

MODIFIERS
Optional list of comma separated HTTP status codes which may be preceded by a single "!" to indicate negation. If the status code is not in the list the literal string "-" will be logged instead of the resulting value from the percent code.
{PARAM}
Parameter string which may be optional depending on the percent code used.
CODE
A one or two character code specified by the table of format codes below.
Format Codes
Format String Description
X

The X character.

%%

The percent character.

%{format}a

The address or host name.

Valid format values are: "server", "client", "local", "remote". The format parameter is optional and defaults to "server".

Values "server" and "client" are the logical addresses which can be modified in the request headers, while "local" and "remote" are the physical addresses so may be the addresses of a proxy between the end-user and the server.

%{format}p

The port.

Valid format values are: "server", "client", "local", "remote". The format parameter is optional and defaults to "server".

Values "server" and "client" are the logical ports which can be modified in the request headers, while "local" and "remote" are the physical ports so may be the ports of a proxy between the end-user and the server.

%{CLF}I

The size of request in bytes, excluding HTTP headers.

The parameter is optional. When the parameter value is "CLF" the Common Log Format is used, i.e. a {@code -} rather than a {@code 0} when no bytes are present.

%{CLF}O

The size of response in bytes, excluding HTTP headers.

The parameter is optional. When the parameter value is "CLF" the Common Log Format is used, i.e. a {@code -} rather than a {@code 0} when no bytes are present.

%{CLF}S

The bytes transferred (received and sent). This is the combination of {@code %I} and {@code %O}.

The parameter is optional. When the parameter value is "CLF" the Common Log Format is used, i.e. a {@code -} rather than a {@code 0} when no bytes are present.

%{VARNAME}C

The value of the request cookie VARNAME.

The parameter is optional. Only version 0 cookies are fully supported. When the parameter is missing, all request cookies will be logged.

%D

The time taken to serve the request, in microseconds.

%{VARNAME}e

The value of the environment variable VARNAME.

%f

The file system path of the requested resource.

%H

The name and version of the request protocol, such as "HTTP/1.1".

%{VARNAME}i

The value of the VARNAME request header.

%k

The number of requests handled on a connection.

The initial request on a connection yields a value 0, the first request after the initial on the same connection yields the value 1, the second request on the same connection yields the value 2, etc.

%m

The HTTP request method.

%{VARNAME}o

The value of the VARNAME response header.

%q

The query string, prepended with a ? if a query string exists, otherwise an empty string.

%r

First line of an HTTP/1.1 request (or equivalent information for HTTP/2 or later).

%R

The name of the Handler or Servlet generating the response (if any).

%s

The HTTP response status code.

%{format|timeZone|locale}t

The time at which the request was received.

The parameter is optional and may have the following values: {format}, {format|timeZone} or {format|timeZone|locale}.

format
Default is e.g. [18/Sep/2011:19:18:28 -0400] where the last number indicates the timezone offset from GMT. Must be in a format supported by the {@code java.time} package.
timeZone
Default is GMT. Must be in a format supported by the {@code java.time} package.
locale
Default is the JVM default locale. Must be in a format supported by {@code java.util.Locale.forLanguageTag()}.
%{UNIT}T

The time taken to serve the request.

The parameter UNIT is optional and defaults to "s". The parameter UNIT indicates the unit of time: "s" for seconds, "ms" for milliseconds, "us" for microseconds. %{us}T is identical to {@code %D}.

%{d}u

The remote user if the request was authenticated with servlet authentication.

May be an invalid value if response status code ({@code %s}) is 401 (unauthorized).

The parameter is optional. When the parameter value is "d", deferred authentication will also be checked.

%U

The URL path requested, not including any query string.

%X

The connection status when response is completed:

X
The connection is aborted before the response completed.
+
The connection may be kept alive after the response is sent.
-
The connection will be closed after the response is sent.
%{VARNAME}ti

The value of the VARNAME request trailer.

%{VARNAME}to

The value of the VARNAME response trailer.

%{OPTION}uri

The request URI.

The parameter is optional and may have the be one of the following options:

%uri
The entire request URI.
%{-query}uri
The entire request URI without the query.
%{-path,-query}uri
The request URI without path or query (so just `scheme://authority`).
%{scheme}uri
The scheme of the request URI.
%{authority}uri
The authority of the request URI.
%{path}uri
The path of the request URI.
%{query}uri
The query of the request URI.
%{host}uri
The host of the request URI.
%{port}uri
The port of the request URI.
%{attributeName}attr

The value of the request attribute with the given name.

Module resources

This module adds the $JETTY_BASE/resources directory to the server’s classpath.

A common use-case for this module is to provide resources for third-party libraries via the server classpath. For instance, many logging libraries (including Log4j2 and Logback) look for their configuration files on the classpath.

Jetty provides a logging library implementation — enabled via the logging-jetty module — whose configuration file is $JETTY_BASE/resources/jetty-logging.properties.

Module rewrite

The rewrite module inserts the RewriteHandler at the beginning of the Handler chain, providing URI-rewriting features similar to the Apache’s mod_rewrite or the Nginx rewrite module.

The module properties are:

## Request attribute name used to store the original request path.
# jetty.rewrite.originalPathAttribute=jetty.rewrite.originalRequestPath

A common use of the rewrite module is to redirect/rewrite old URI paths that have been renamed, for example from /old/* to /new/*; in this way, the old paths will not result in a 404 response, but rather be redirected/rewritten to the new paths.

RewriteHandler matches incoming requests against a set of rules that you can specify in the $JETTY_BASE/etc/jetty-rewrite-rules.xml file.

Rules can be matched against request data such as the request URI or the request headers; if there is a match, the rule is applied.

The rule file $JETTY_BASE/etc/jetty-rewrite-rules.xml is initially empty, but contains commented examples of rules that you can add.

The list of available rules can be found here.

An example of jetty-rewrite-rules.xml is the following:

jetty-rewrite-rules.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
  <Call name="addRule">
    <!-- Redirect with a 301 from /old/* to /new/* -->
    <Arg>
      <New class="org.eclipse.jetty.rewrite.handler.RedirectRegexRule">
        <Set name="statusCode">301</Set>
        <Set name="pattern">/old/(.*)</Set>
        <Set name="location">/new/$1</Set>
      </New>
    </Arg>
  </Call>
</Configure>

Rules can be scoped to a specific virtual host. In the example below, the rule will only be evaluated if the virtual host matches example.com:

jetty-rewrite-rules.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
  <Call name="addRule">
    <Arg>
      <New class="org.eclipse.jetty.rewrite.handler.VirtualHostRuleContainer">
        <Call name="addVirtualHost">
          <!-- Only match the example.com domain -->
          <Arg>example.com</Arg>
        </Call>
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
              <Set name="pattern">/advice</Set>
              <Set name="location">/support</Set>
            </New>
          </Arg>
        </Call>
      </New>
    </Arg>
  </Call>
</Configure>

Module server

The server module provides generic server support, and configures generic HTTP properties that apply to all HTTP protocols, the scheduler properties and the server specific properties.

The server module depends on the threadpool module, the bytebufferpool module and the logging module.

The server module configures the shared parameters for generic HTTP handling, but does not enable any specific network protocol. You have to explicitly enable the protocols you want to support by enabling, for example, the http module for clear-text HTTP/1.1 support, or the http2 module for secure HTTP/2 support, etc.

See also the protocols section for more information about the supported protocols.

HTTP Configuration Properties

The module properties to configure generic HTTP properties are listed below. Mostly they frequently apply to HTTP/1, HTTP/2 and HTTP/3, but some parameters are version specific:

### Common HTTP configuration
## Scheme to use to build URIs for secure redirects
# jetty.httpConfig.secureScheme=https

## Port to use to build URIs for secure redirects
# jetty.httpConfig.securePort=8443

## Response content buffer size (in bytes)
# jetty.httpConfig.outputBufferSize=32768

## Max response content write length that is buffered (in bytes)
# jetty.httpConfig.outputAggregationSize=8192

## If HTTP/1.x persistent connections should be enabled
# jetty.httpConfig.persistentConnectionsEnabled=true

## Max request headers size (in bytes)
# jetty.httpConfig.requestHeaderSize=8192

## Max response headers size (in bytes)
# jetty.httpConfig.responseHeaderSize=8192

## Whether to send the Server: header
# jetty.httpConfig.sendServerVersion=true

## Whether to send the Date: header
# jetty.httpConfig.sendDateHeader=false

## Max per-connection header cache size (in nodes)
# jetty.httpConfig.headerCacheSize=1024

## Whether, for requests with content, delay dispatch until some content has arrived
# jetty.httpConfig.delayDispatchUntilContent=true

## Maximum number of error dispatches to prevent looping
# jetty.httpConfig.maxErrorDispatches=10

## Relative Redirect Locations allowed
# jetty.httpConfig.relativeRedirectAllowed=true

## Whether to use direct ByteBuffers for reading or writing
# jetty.httpConfig.useInputDirectByteBuffers=true
# jetty.httpConfig.useOutputDirectByteBuffers=true

Among the configurable properties, the most relevant are:

jetty.httpConfig.headerCacheSize

The header cache is used when parsing HTTP/1 to more efficiently handle fields that are repeated in every request on a connection. If the server does not receive persistent connection or infrequent repeated fields, then there may be a performance gain in reducing the cache size. If large fields are frequently repeated, then a large cache may be beneficial.

jetty.httpConfig.delayDispatchUntilContent

It is not uncommon for the network packets containing a request header to arrive before packets that contain the data of any request body. In such cases it may be beneficial for overall performance to delay dispatching the request to be handled until the first data packet arrives, as this may avoid blocking the handling thread. However, if minimum latency for receiving the request without content is important, then this parameter can be set to false.

jetty.httpConfig.sendServerVersion

Whether you want to send the Server header in every HTTP response:

HTTP/1.1 200 OK
Content-Length: 0
Server: Jetty(12.0.15-SNAPSHOT)

Server Configuration Properties

The module properties to configure the Jetty server are:

### Server configuration
## Whether ctrl+c on the console gracefully stops the Jetty server
# jetty.server.stopAtShutdown=true

## Timeout in ms to apply when stopping the server gracefully
# jetty.server.stopTimeout=5000

## Dump the state of the Jetty server, components, and webapps after startup
# jetty.server.dumpAfterStart=false

## The temporary directory used by the Jetty server and as a root for its contexts
# jetty.server.tempDirectory=

## Dump the state of the Jetty server, components, and webapps before shutdown
# jetty.server.dumpBeforeStop=false

Among the configurable properties, the most relevant are:

jetty.server.dumpAfterStart

Whether to perform a Server.dump() operation after the Server has started. The output of the dump operation is sent to System.err. See also the Jetty Server Dump section for more information.

jetty.server.dumpBeforeStop

Whether to perform a Server.dump() operation before the Server stops. The output of the dump operation is sent to System.err. See also the Jetty Server Dump section for more information.

jetty.server.stopAtShutdown

Whether to call Server.stop() through a JVM shutdown hook when the JVM exits.

Server Compliance Properties

The Jetty server strives to keep up with the latest IETF RFCs for compliance with internet specifications, which are periodically updated. When possible, Jetty will support backwards compatibility by providing compliance modes that can be configured to allow violations of the current specifications that may have been allowed in obsoleted specifications. The module properties to configure the Jetty server compliance are:

## HTTP Compliance: RFC7230, RFC7230_LEGACY, RFC2616, RFC2616_LEGACY, LEGACY
# jetty.httpConfig.compliance=RFC7230

## URI Compliance: DEFAULT, LEGACY, RFC3986, RFC3986_UNAMBIGUOUS, UNSAFE
# jetty.httpConfig.uriCompliance=DEFAULT

## Cookie compliance mode for parsing request Cookie headers: RFC6265_STRICT, RFC6265, RFC6265_LEGACY, RFC2965, RFC2965_LEGACY
# jetty.httpConfig.requestCookieCompliance=RFC6265

## Cookie compliance mode for generating response Set-Cookie: RFC2965, RFC6265
# jetty.httpConfig.responseCookieCompliance=RFC6265

Among the configurable properties, the most relevant are:

jetty.httpConfig.compliance

Configures the compliance to HTTP specifications. The value could be:

  • One of the predefined HttpCompliance constants, such as RFC7230 or RFC2616. For example: jetty.httpConfig.compliance=RFC2616.

  • A comma-separated list of violations to allow or forbid, as specified by the HttpCompliance.from(String) method. For example, jetty.httpConfig.compliance=RFC7230,MULTIPLE_CONTENT_LENGTHS means that the HTTP compliance is that defined by RFC7230, but also allows the HttpCompliance.Violation.MULTIPLE_CONTENT_LENGTHS, so that requests that have multiple Content-Length headers are accepted (they would be rejected when using just HttpCompliance.RFC7230).

    For more information about HttpCompliance see also this section.

jetty.httpConfig.uriCompliance

Configures the compliance to URI specifications. The value could be:

  • One of the predefined UriCompliance constants, such as DEFAULT or RFC3986. For example: jetty.httpConfig.compliance=RFC3986.

  • A comma-separated list of violations to allow or forbid, as specified by the UriCompliance.from(String) method. For example, jetty.httpConfig.uriCompliance=RFC3986,-AMBIGUOUS_PATH_SEPARATOR means that the URI compliance is that defined by RFC3986, but also does not allow the UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR, so that requests that have URIs such as /foo/bar%2Fbaz (where %2F is the URL-encoded / character) are rejected (they would be accepted when using just UriCompliance.RFC3986).

    For more information about UriCompliance see also this section.

jetty.httpConfig.requestCookieCompliance
jetty.httpConfig.responseCookieCompliance

Configures the compliance to HTTP cookie specifications. The value could be:

  • One of the predefined CookieCompliance constants, such as RFC6265. For example: jetty.httpConfig.compliance=RFC6265.

  • A comma-separated list of violations to allow or forbid, as specified by the CookieCompliance.from(String) method. For example, jetty.httpConfig.requestCookieCompliance=RFC6265,-RESERVED_NAMES_NOT_DOLLAR_PREFIXED means that the cookie compliance is that defined by RFC6265, but also does not allow the CookieCompliance.Violation.RESERVED_NAMES_NOT_DOLLAR_PREFIXED, so that requests that have cookie headers such as Cookie: $foo=bar are rejected (they would be accepted when using just CookieCompliance.RFC6265).

    For more information about CookieCompliance see also this section.

Server Scheduler Configuration Properties

The module properties to configure the Jetty server scheduler are:

### Server Scheduler Configuration
## The scheduler thread name, defaults to "Scheduler-{hashCode()}" if blank.
# jetty.scheduler.name=

## Whether the server scheduler threads are daemon.
# jetty.scheduler.daemon=false

## The number of server scheduler threads.
# jetty.scheduler.threads=1

Module ssl

The ssl module provides the secure connector, and allows you to configure the KeyStore properties and the TLS parameters, and depends on the server module.

Secure Connector Properties

The module properties to configure the secure connector are:

### TLS (SSL) Connector Configuration

## The host/address to bind the connector to.
# jetty.ssl.host=0.0.0.0

## The port the connector listens on.
# jetty.ssl.port=8443

## The connector idle timeout, in milliseconds.
# jetty.ssl.idleTimeout=30000

## The number of acceptors (-1 picks a default value based on number of cores).
# jetty.ssl.acceptors=1

## The number of selectors (-1 picks a default value based on number of cores).
# jetty.ssl.selectors=-1

## The ServerSocketChannel accept queue backlog (0 picks the platform default).
# jetty.ssl.acceptQueueSize=0

## The thread priority delta to give to acceptor threads.
# jetty.ssl.acceptorPriorityDelta=0

## Whether to enable the SO_REUSEADDR socket option.
# jetty.ssl.reuseAddress=true

## Whether to enable the SO_REUSEPORT socket option.
# jetty.ssl.reusePort=false

## Whether to enable the TCP_NODELAY socket option on accepted sockets.
# jetty.ssl.acceptedTcpNoDelay=true

## The SO_RCVBUF socket option to set on accepted sockets.
## A value of -1 indicates that the platform default is used.
# jetty.ssl.acceptedReceiveBufferSize=-1

## The SO_SNDBUF socket option to set on accepted sockets.
## A value of -1 indicates that the platform default is used.
# jetty.ssl.acceptedSendBufferSize=-1

## Whether client SNI data is required for all secure connections.
## When SNI is required, clients that do not send SNI data are rejected with an HTTP 400 response.
# jetty.ssl.sniRequired=false

## Whether client SNI data is checked to match CN and SAN in server certificates.
## When SNI is checked, if the match fails the connection is rejected with an HTTP 400 response.
# jetty.ssl.sniHostCheck=true

## The max age, in seconds, for the Strict-Transport-Security response header.
# jetty.ssl.stsMaxAgeSeconds=31536000

## Whether to include the subdomain property in any Strict-Transport-Security header.
# jetty.ssl.stsIncludeSubdomains=true

Among the configurable properties, the most relevant are:

jetty.ssl.port

The network port that Jetty listens to for secure connections — default 8443.

jetty.ssl.idleTimeout

The amount of time a connection can be idle (i.e. no bytes received and no bytes sent) until the server decides to close it to save resources — default 30000 milliseconds.

jetty.ssl.acceptors

The number of threads that compete to accept connections — default 1. Use -1 to let the accept heuristic decides the value; the current heuristic calculates a value based on the number of cores). Refer to this section for more information about acceptor threads.

jetty.ssl.selectors

The number of NIO selectors (with an associated thread) that manage connections — default -1 (i.e. a select heuristic decides the value; the current heuristic calculates a value based on the number of cores). Refer to this section for more information about selector threads.

The module properties to configure the KeyStore and TLS parameters are:

### SslContextFactory Configuration
## Note that OBF passwords are not secure, just protected from casual observation.

## Whether client SNI data is required for all secure connections.
## When SNI is required, clients that do not send SNI data are rejected with a TLS handshake error.
# jetty.sslContext.sniRequired=false

## The Endpoint Identification Algorithm.
## Same as javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String).
# jetty.sslContext.endpointIdentificationAlgorithm=

## The JSSE Provider.
# jetty.sslContext.provider=

## The KeyStore file path, either an absolute path or a relative path to $JETTY_BASE.
# jetty.sslContext.keyStorePath=etc/keystore.p12

## The TrustStore file path, either an absolute path or a relative path to $JETTY_BASE.
# jetty.sslContext.trustStorePath=etc/keystore.p12

## The KeyStore password.
# jetty.sslContext.keyStorePassword=

## The Keystore type.
# jetty.sslContext.keyStoreType=PKCS12

## The KeyStore provider.
# jetty.sslContext.keyStoreProvider=

## The KeyManager password.
# jetty.sslContext.keyManagerPassword=

## The TrustStore password.
# jetty.sslContext.trustStorePassword=

## The TrustStore type.
# jetty.sslContext.trustStoreType=PKCS12

## The TrustStore provider.
# jetty.sslContext.trustStoreProvider=

## Whether client certificate authentication is required.
# jetty.sslContext.needClientAuth=false

## Whether client certificate authentication is desired, but not required.
# jetty.sslContext.wantClientAuth=false

## Whether cipher order is significant.
# jetty.sslContext.useCipherSuitesOrder=true

## The SSLSession cache size.
# jetty.sslContext.sslSessionCacheSize=-1

## The SSLSession cache timeout (in seconds).
# jetty.sslContext.sslSessionTimeout=-1

## Whether TLS renegotiation is allowed.
# jetty.sslContext.renegotiationAllowed=true

## The max number of TLS renegotiations per connection.
# jetty.sslContext.renegotiationLimit=5

KeyStore Properties and TLS Properties

The Jetty component that manages the KeyStore, that contains the cryptographic material and the TLS configuration is an instance of SslContextFactory.Server.

You can configure the SslContextFactory.Server by specifying properties, or by invoking its method for a more advanced configuration.

Among the configurable properties, the most relevant are:

jetty.sslContext.keyStorePath

The KeyStore path on the file system, either an absolute path or a relative path to $JETTY_BASE — defaults to $JETTY_BASE/etc/keystore.p12.

jetty.sslContext.keyStorePassword

The KeyStore password, which you want to explicitly configure. The password may be obfuscated with the Jetty Password tool.

If you need to configure client certificate authentication, you want to configure one of these properties (they are mutually exclusive):

jetty.sslContext.needClientAuth

Whether client certificate authentication should be required.

jetty.sslContext.wantClientAuth

Whether client certificate authentication should be requested.

If you configure client certificate authentication, you need to configure and distribute a client KeyStore as explained in this section.

Advanced TLS Configuration

Configuring SslContextFactory.Server using properties as explained in this section is sufficient for most cases.

For the cases where Jetty module properties are not defined, or when you need more advanced configuration (for example the ability to include and/or exclude the TLS cipher suites), you can follow these steps:

  1. Modify $JETTY_BASE/start.d/ssl.ini by adding a path to a custom XML file, for example:

    ssl.ini
    --module=ssl
    etc/ssl-config.xml (1)
    ...
    1 The path to the custom XML file, relative to $JETTY_BASE.
  2. Create the custom XML file, with your advanced configuration. For example, to exclude certain TLS ciphers you can use the following file:

    ssl-config.xml
    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://jetty.org/jetty/configure_10_0.dtd">
    
    <Configure>
      <Ref refid="sslContextFactory"> (1)
        <!-- Example using the Set element -->
        <Set name="ExcludeCipherSuites"> (2)
          <Array type="String">
            <Item>^TLS_RSA_.*$</Item>
            <Item>^.*_(MD5|SHA|SHA1)$</Item>
          </Array>
        </Set>
        <!-- Example using the Call element -->
        <Call name="addExcludeCipherSuites">
          <Arg>
            <Array type="String">
              <Item>^SSL_.*$</Item>
            </Array>
          </Arg>
        </Call>
      </Ref>
    </Configure>
    1 Reference the existing sslContextFactory object.
    2 Call the method setExcludeCipherSuites(String...) to specify regular expressions of the TLS ciphers you want to exclude.

The syntax to use in the custom XML file is described in this section.

In the custom XML file you can call any SslContextFactory.Server method. Refer to the SslContextFactory.Server javadocs for the comprehensive list of methods.

Module ssl-reload

The ssl-reload module provides a periodic scanning of the directory where the KeyStore file resides. When the scanning detects a change to the KeyStore file, the correspondent SslContextFactory.Server component is reloaded with the new KeyStore configuration.

The module properties are:

# Monitored directory scan period, in seconds.
# jetty.sslContext.reload.scanInterval=1

Module state-tracking

The state-tracking Jetty module inserts the StateTrackingHandler at the beginning of the Handler chain.

StateTrackingHandler is a troubleshooting Handler that tracks usages of Handler/Request/Response asynchronous APIs, and logs at warning level invalid usages of the APIs that may lead to blockages, deadlocks, or missing completion of Callbacks.

This module can be enabled to troubleshoot web applications that do not behave as expected, for example:

  • That consume a lot of threads (possibly because they block).

  • That do not send responses (or send only partial responses) to clients.

  • That timeout when apparently they have received or have sent all data.

The module properties are:

## The timeout in ms for the completion of the handle() callback.
# jetty.stateTracking.handlerCallbackTimeout=0

## Whether the handle() callback is completed in case of timeout.
# jetty.stateTracking.completeHandlerCallbackAtTimeout=false

## The timeout in ms for the execution of the demand callback.
# jetty.stateTracking.demandCallbackTimeout=0

## The timeout in ms for the execution of a response write.
# jetty.stateTracking.writeTimeout=0

## The timeout in ms for the execution of the response write callback.
# jetty.stateTracking.writeCallbackTimeout=0

Module test-keystore

The test-keystore module creates on-the-fly a KeyStore containing a self-signed certificate for domain localhost. The KeyStore file is automatically deleted when the JVM exits, and re-created when you restart Jetty, to enforce the fact that it is a test KeyStore that should not be reused if not for testing.

The module file is $JETTY_HOME/modules/test-keystore.mod:

[description]
Test keystore with self-signed SSL Certificate.
DO NOT USE IN PRODUCTION!!!

[tags]
demo
ssl

[before]
ssl

[files]
maven://org.bouncycastle/bcpkix-jdk15to18/${bouncycastle.version}|lib/bouncycastle/bcpkix-jdk15to18-${bouncycastle.version}.jar
maven://org.bouncycastle/bcprov-jdk15to18/${bouncycastle.version}|lib/bouncycastle/bcprov-jdk15to18-${bouncycastle.version}.jar
maven://org.bouncycastle/bcutil-jdk15to18/${bouncycastle.version}|lib/bouncycastle/bcutil-jdk15to18-${bouncycastle.version}.jar

[lib]
lib/jetty-keystore-${jetty.version}.jar
lib/bouncycastle/bcpkix-jdk15to18-${bouncycastle.version}.jar
lib/bouncycastle/bcprov-jdk15to18-${bouncycastle.version}.jar
lib/bouncycastle/bcutil-jdk15to18-${bouncycastle.version}.jar

[xml]
etc/jetty-test-keystore.xml

[ini]
bouncycastle.version?=1.78.1
jetty.webapp.addHiddenClasses+=,${jetty.base.uri}/lib/bouncycastle/
jetty.sslContext.keyStorePath?=etc/test-keystore.p12
jetty.sslContext.keyStoreType?=PKCS12
jetty.sslContext.keyStorePassword?=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4

Note how properties jetty.sslContext.keyStorePath and jetty.sslContext.keyStorePassword are configured, only if not already set (via the ?= operator), directly in the module file, rather than in a *.ini file. This is done to avoid that these properties accidentally overwrite a real KeyStore configuration.

Module threadpool

The threadpool module allows you to configure the server-wide thread pool.

The thread pool creates threads on demand up to maxThreads, and idles them out if they are not used.

Since Jetty uses the thread pool internally to execute critical tasks, it is not recommended to constrain the thread pool to small values of maxThreads with the purpose of limiting HTTP request concurrency, as this could very likely cause a server lockup when Jetty needs to run a critical task but there are no threads available. Start with the default value of maxThreads, and tune for larger values if needed.

The module properties to configure the thread pool are:

## Thread name prefix.
#jetty.threadPool.namePrefix=qtp<hashCode>

## Minimum number of pooled threads.
#jetty.threadPool.minThreads=10

## Maximum number of pooled threads.
#jetty.threadPool.maxThreads=200

## Number of reserved threads (-1 for heuristic).
#jetty.threadPool.reservedThreads=-1

## Whether to use virtual threads, if the runtime supports them.
## Deprecated, use Jetty module 'threadpool-virtual' instead.
#jetty.threadPool.useVirtualThreads=false

## Thread idle timeout (in milliseconds).
#jetty.threadPool.idleTimeout=60000

## The max number of idle threads that are evicted in one idleTimeout period.
#jetty.threadPool.maxEvictCount=1

## Whether to output a detailed dump.
#jetty.threadPool.detailedDump=false

Among the configurable properties, the most relevant are:

jetty.threadPool.namePrefix

The name prefix to use for the thread names.

jetty.threadPool.detailedDump

Whether the thread pool should dump the whole stack trace of each thread, or just the topmost stack frame — defaults to false.

jetty.threadPool.idleTimeout

The time, in milliseconds, after which an idle thread is released from the pool — defaults to 60000, i.e. 60 seconds.

jetty.threadPool.maxThreads

The max number of threads pooled by the thread pool — defaults to 200.

If you want to use virtual threads, introduced as a preview feature in Java 19 and Java 20, and become an official feature since Java 21, use the following modules:

Module threadpool-all-virtual

The threadpool-all-virtual module allows you to configure the server-wide thread pool, similarly to what you can do with the threadpool Jetty module, so that all threads are virtual threads, introduced as an official feature since Java 21.

Only use this module if you are using Java 21 or later.

The module properties to configure the thread pool are:

## Virtual threads name prefix.
#jetty.threadPool.namePrefix=vtp<hashCode>

## Maximum number of current virtual threads.
#jetty.threadPool.maxThreads=200

## Whether to track virtual threads so they appear
## in the dump even if they are unmounted.
#jetty.threadPool.tracking=false

## Whether to output virtual thread's stack traces in the dump.
#jetty.threadPool.detailedDump=false

The property jetty.threadpool.maxThreads limits, using a Semaphore, the number of current virtual threads in use.

Please refer to the virtual threads section of the Jetty Threading Architecture for more information about virtual threads and their pitfalls.

Module threadpool-virtual

The threadpool-virtual module allows you to configure the server-wide thread pool, similarly to what you can do with the threadpool Jetty module, but also specify to use virtual threads, introduced as an official feature since Java 21.

Only use this module if you are using Java 21 or later. If you are using Java 19 or Java 20, use the threadpool-virtual-preview Jetty module instead.

Refer to the threadpool Jetty module for the general features provided by that Jetty module that also this Jetty module provides.

The module properties to configure the thread pool are:

## Platform threads name prefix.
#jetty.threadPool.namePrefix=qtp<hashCode>

## Minimum number of pooled threads.
#jetty.threadPool.minThreads=10

## Maximum number of pooled threads.
#jetty.threadPool.maxThreads=200

## Number of reserved threads (-1 for heuristic).
#jetty.threadPool.reservedThreads=-1

## Thread idle timeout (in milliseconds).
#jetty.threadPool.idleTimeout=60000

## The max number of idle threads that can be evicted in one idleTimeout period.
#jetty.threadPool.maxEvictCount=1

## Whether to output a detailed dump.
#jetty.threadPool.detailedDump=false

## Virtual threads name prefix.
#jetty.threadPool.virtual.namePrefix=qtp<hashCode>-virtual-

## Max number of current virtual threads.
#jetty.threadPool.virtual.maxThreads=200

## Whether to track virtual threads so they appear
## in the dump even if they are unmounted.
#jetty.threadPool.virtual.tracking=false

The specific properties to configure virtual threads are:

jetty.threadPool.virtual.namePrefix

The name prefix to use for the virtual thread names.

jetty.threadPool.virtual.inheritInheritableThreadLocals

Whether virtual threads inherit the values of InheritableThreadLocal variables.

Module threadpool-virtual-preview

The threadpool-virtual-preview module allows you to configure the server-wide thread pool, similarly to what you can do with the threadpool Jetty module, but also specify to use virtual threads, introduced as a preview feature in Java 19 and in Java 20.

Only use this module if you are using Java 19 or Java 20. If you are using Java 21 or later, use the threadpool-virtual Jetty module instead.
To enable preview features, this module needs to specify the --enable-preview command line option using the [exec] directive, and as such it will fork another JVM.

Refer to the threadpool Jetty module for the general features provided by that Jetty module that also this Jetty module provides.

The module properties to configure the thread pool are:

## Platform threads name prefix.
#jetty.threadPool.namePrefix=qtp<hashCode>

## Minimum number of pooled threads.
#jetty.threadPool.minThreads=10

## Maximum number of pooled threads.
#jetty.threadPool.maxThreads=200

## Number of reserved threads (-1 for heuristic).
#jetty.threadPool.reservedThreads=-1

## Thread idle timeout (in milliseconds).
#jetty.threadPool.idleTimeout=60000

## The max number of idle threads that can be evicted in one idleTimeout period.
#jetty.threadPool.maxEvictCount=1

## Whether to output a detailed dump.
#jetty.threadPool.detailedDump=false

## Virtual threads name prefix.
#jetty.threadPool.virtual.namePrefix=qtp<hashCode>-virtual-

## Whether virtual threads are allowed to set thread locals.
#jetty.threadPool.virtual.allowSetThreadLocals=true

## Whether virtual threads inherits the values of inheritable thread locals.
#jetty.threadPool.virtual.inheritInheritableThreadLocals=true

The specific properties to configure virtual threads are:

jetty.threadPool.virtual.namePrefix

The name prefix to use for the virtual thread names.

jetty.threadPool.virtual.allowSetThreadLocals

Whether virtual threads are allowed to set thread locals.

jetty.threadPool.virtual.inheritInheritableThreadLocals

Whether virtual threads inherit the values of InheritableThreadLocal variables.

Module well-known

The well-known Jetty module creates a ResourceHandler deployed at the /.well-known context path which serves files from a directory. By default, the directory created at $JETTY_BASE/.well-known is used, but it can be configured from well-known.ini to anywhere in the filesystem. Note that the .well-known directory may be seen as a hidden directory by the filesystem.

The concept of well-known URIs has been defined in RFC5785. This module can be used for things like the automatic renewal of Let’s Encrypt certificates. See IANA Well-Known URIs for more possible examples of how this can be used.

The module properties are:

## Well Known Directory (relative to $JETTY_BASE if relative path, otherwise it is an absolute path).
# jetty.wellknown.dir=.well-known

## Allow contents of the well-known directory to be listed.
# jetty.wellknown.listDirectories=false