JEP draft: HTTP over Unix Domain Sockets
| Owner | Michael McMahon |
| Type | Feature |
| Scope | JDK |
| Status | Draft |
| Component | core-libs / java.net |
| Discussion | net dash dev at openjdk dot org |
| Effort | S |
| Duration | M |
| Reviewed by | Alan Bateman |
| Created | 2026/02/12 15:35 |
| Updated | 2026/04/01 13:17 |
| Issue | 8377806 |
Summary
Add Unix domain (AF_UNIX) socket support to the java.net.http API, HTTP server API and the jwebserver command line tool in the JDK.
Goals
- Support HTTP client and server applications that communicate within a single host environment, or between containers on the same host, bypassing the TCP/IP network stack.
- Support both the
httpandhttpsschemes. - Introduce new command-line options to the
jwebservertool to allow serving HTTP requests over a Unix domain socket.
Non-Goals
- It is a non-goal to add support to the legacy HttpURLConnection API
- It is a non-goal to provide support for QUIC and HTTP/3 (both client and server)
- It is a non-goal to add support for new HTTP protocol versions on the server (beyond HTTP/1.1)
- It is a non-goal to support Unix domain sockets through special URL schemes or other structure imposed on URLs
Motivation
Unix domain sockets are used for inter-process communication (IPC) on the same host. They are similar to TCP/IP sockets in most respects, except that they are addressed by file system path names rather than Internet Protocol (IP) addresses and port numbers. For local HTTP access with both client and server on the same system, Unix domain sockets are both more secure and more efficient than TCP/IP loopback connections.
-
Unix domain sockets are strictly for communication between processes on the same system. Applications that are not intended to accept remote connections can improve security by using Unix domain sockets.
-
Unix domain sockets are further protected by operating-system enforced, filesystem-based access controls.
-
Unix domain sockets have faster setup times and higher data throughput than TCP/IP loopback connections.
-
Unix domain sockets may be a better solution than TCP/IP sockets for container environments, where communication between containers on the same system is required. This can be achieved using sockets located in shared volumes.
Unix domain sockets have long been a feature of most Unix platforms, and have been supported in Windows since Windows 10 and Windows Server 2019.
It would greatly benefit applications deployed in containers if the HTTP client and server APIs in a local IPC environment could use Unix domain sockets, due to their greater security and performance in these local environments.
Description
APIs will be enhanced in the java.net.http and jdk.httpserver modules to specify:
- A file system path (representing a Unix domain socket) as the local address for a server endpoint
- A file system path (representing a Unix domain socket) as the remote address for a particular client HTTP request
These parameters will be entirely independent of request URIs including any domain name specified in a request URI.
The command line arguments for the jwebserver tool will be extended to allow binding to a Unix domain socket address.
HTTP Client changes
In the java.net.http module, java.net.http.HttpOption interface will be extended with the ALT_TRANSPORT_ADDRESS class, which has a type parameter of type java.net.SocketAddress but which initially only supports UnixDomainSocketAddress.
Users will be able to pass the target Unix domain socket address using HttpRequest.Builder::setOption:
Using HttpRequest::setOption will allow the Unix domain socket address to be provided entirely independent of request URIs, including any domain name specified in a request URI.
HTTP/3 will not be supported over Unix domain sockets.
If the preferred version is set to HTTP/3 using HttpClient.Builder::version and HttpRequest.Builder::version methods, the request will be downgraded to HTTP/2 or HTTP/1.1.
Similarly, the HttpOption.H3_DISCOVERY option, if present, will be ignored.
The typical usage for client Unix domain sockets (unlike TCP/IP sockets) is that their local addresses remain unbound.
This approach will be adapted in HttpClient too. Binding the client connections to specific local Unix domain socket addresses will not supported.
HTTP Server changes
In the jdk.httpserver module, create and bind methods of com.sun.net.HttpServer and com.sun.net.HttpsServer classes that accept java.net.InetSocketAddress will take java.net.SocketAddress instead.
This will effectively enable users to be able to provide both java.net.InetSocketAddress and java.net.UnixDomainSocketAddress while creating or binding HttpServer or HttpsServer instances:
The file path pointed by the Unix domain socket will be created while binding the server, and will be removed on server termination. If the file already exists, the socket bind, and consequently the server start will fail.
The following new methods will be added (or modified) for the HTTP server Unix domain socket support:
- HttpServerProvider::createHttpServer(UnixDomainSocketAddress addr, int backlog)
- HttpsServerProvider::createHttpsServer(UnixDomainSocketAddress addr, int backlog)
- HttpServer::create(SocketAddress addr, int backlog) // plus other variants; modified
- HttpServer::createUnixDomain()
- SimpleFileServer::createFileServer(SocketAddress address, Path rootDirectory, OutputLevel outputLevel) // modified
Example of a HTTP client and server in two different Docker containers
Setting up a volume to be shared by the two containers
# creates a shareable volume called myvol
docker volume create myvol
# Runs a (shell) image with a JDK installed, in a container, with "myvol" mounted on /mnt.
# Run this command twice to create the client and server containers
docker run --mount 'type=volume,destination=/mnt,src=myvol' -it jdk_28 sh
HTTP server
The following snippet shows a server running in the server container, binding to a Unix domain socket in the shared volume at /mnt/server.sock
public class Server {
void main() throws IOException {
var path = Path.of("/mnt/server.sock");
Files.deleteIfExists(path);
var addr = UnixDomainSocketAddress.of(path);
var server = HttpServer.create(addr, 5);
server.createContext("/",
(ex) -> {
var str = "Hello world!";
ex.sendResponseHeaders(200, str.length());
ex.getResponseBody().write(str.getBytes(StandardCharsets.ISO_8859_1));
ex.close();
});
server.start();
System.out.printf("Listening at: %s\n", server.getSocketAddress().toString());
}
}
HTTP client
The following is an example HTTP client running in the client container, which connects to the server bound to the socket /mnt/server.sock in the shared volume
public class Client {
void main() throws IOException, InterruptedException {
try (var client = HttpClient.newHttpClient()) {
var request = HttpRequest.newBuilder()
.uri(URI.create("https://foo.com/uri"))
.setOption(
HttpOption.ALT_TRANSPORT_ADDRESS,
UnixDomainSocketAddress.of("/mnt/server.sock"))
.GET()
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
// ...
}
}
}
Alternatives
One high level design question was whether to configure the use of Unix domain sockets as something tied to URL structure (such as the use of special schemes, or special reserved host names, or paths) or to use a side configuration mechanism independent of any URL that might be used by applications.
A survey of existing libraries and frameworks quickly showed that none of them achieve this by imposing a particular structure on URLs and the universally accepted way is to use specific APIs for configuring this.
Risks and Assumptions
One possible risk is that subtle behavior differences between TCP and Unix domain sockets impacts the operation of the HTTP protocol. If this occurs, it may need to be accounted for in the apidoc.
There is a discussion of these differences in the following article
Dependencies
This builds on the work of JEP 380: "Unix domain socket channels" which implemented Unix domain sockets in NIO socket channels.