spring-projects/spring-boot · error · SocketException
Socket is closed
Error message
Socket is closed
What it means
UnixDomainSocket.getInputStream (and getOutputStream) check isClosed() first and throw SocketException('Socket is closed') if the socket has been closed. This mirrors the contract of java.net.Socket. The socket is closed by close() (which also closes the underlying SocketChannel). Any subsequent attempt to obtain a stream fails.
Source
Thrown at buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/socket/UnixDomainSocket.java:59
* @throws IOException if the socket cannot be opened
*/
public static Socket get(String path) throws IOException {
return new UnixDomainSocket(path);
}
private final SocketAddress socketAddress;
private final SocketChannel socketChannel;
private UnixDomainSocket(String path) throws IOException {
this.socketAddress = UnixDomainSocketAddress.of(path);
this.socketChannel = SocketChannel.open(this.socketAddress);
}
@Override
public InputStream getInputStream() throws IOException {
if (isClosed()) {
throw new SocketException("Socket is closed");
}
if (!isConnected()) {
throw new SocketException("Socket is not connected");
}
if (isInputShutdown()) {
throw new SocketException("Socket input is shutdown");
}
return Channels.newInputStream(this.socketChannel);
}
@Override
public OutputStream getOutputStream() throws IOException {
if (isClosed()) {
throw new SocketException("Socket is closed");
}
if (!isConnected()) {
throw new SocketException("Socket is not connected");View on GitHub (pinned to 270dfe353f)
Solutions
- Do not use the socket after close(); move all I/O inside the socket's try-with-resources block.
- If the socket is pooled, reopen it via UnixDomainSocket.get(path) after eviction.
- Audit for double-close or shared references that close out from under a reader.
Example fix
// before
try (Socket s = UnixDomainSocket.get(path)) {
// ...
}
return s.getInputStream(); // throws "Socket is closed"
// after
try (Socket s = UnixDomainSocket.get(path);
InputStream in = s.getInputStream()) {
// read here
} Defensive patterns
Strategy: validation
Validate before calling
// Guard before obtaining a stream
if (socket.isClosed()) {
socket = UnixDomainSocket.get(path); // reopen
}
InputStream in = socket.getInputStream(); Try / catch
try {
socket.getInputStream();
} catch (java.net.SocketException ex) {
if ("Socket is closed".equals(ex.getMessage())) {
socket = UnixDomainSocket.get(path); // reopen and retry once
} else throw ex;
} Prevention
- Scope all I/O within the socket's try-with-resources block.
- Never share a socket across closers in different threads.
- After closing a pooled socket, drop all references that could read from it.
When it happens
Trigger: getInputStream() or getOutputStream() is called after close() ran — either an explicit close() call or a try-with-resources that exited.
Common situations: A try-with-resources around the socket followed by a read outside the block; a connection pool evicting and closing an idle socket while another thread still holds a reference; double-close.
Related errors
- Socket is not connected
- Socket input is shutdown
- Docker API version must be at least %s to support this featu
- Error response received when pushing image: {}
- %s' exited with code %d: %s
AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11).
Data as JSON: /api/errors/c3cad0e6623e4e5a.
Report an issue: GitHub.