{"record":{"id":"69195dee725dd1a0","repo":"spring-projects/spring-boot","slug":"socket-input-is-shutdown","errorCode":null,"errorMessage":"Socket input is shutdown","messagePattern":"Socket input is shutdown","errorType":"exception","errorClass":"SocketException","httpStatus":null,"severity":"error","filePath":"buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/socket/UnixDomainSocket.java","lineNumber":65,"sourceCode":"\tprivate final SocketAddress socketAddress;\n\n\tprivate final SocketChannel socketChannel;\n\n\tprivate UnixDomainSocket(String path) throws IOException {\n\t\tthis.socketAddress = UnixDomainSocketAddress.of(path);\n\t\tthis.socketChannel = SocketChannel.open(this.socketAddress);\n\t}\n\n\t@Override\n\tpublic InputStream getInputStream() throws IOException {\n\t\tif (isClosed()) {\n\t\t\tthrow new SocketException(\"Socket is closed\");\n\t\t}\n\t\tif (!isConnected()) {\n\t\t\tthrow new SocketException(\"Socket is not connected\");\n\t\t}\n\t\tif (isInputShutdown()) {\n\t\t\tthrow new SocketException(\"Socket input is shutdown\");\n\t\t}\n\n\t\treturn Channels.newInputStream(this.socketChannel);\n\t}\n\n\t@Override\n\tpublic OutputStream getOutputStream() throws IOException {\n\t\tif (isClosed()) {\n\t\t\tthrow new SocketException(\"Socket is closed\");\n\t\t}\n\t\tif (!isConnected()) {\n\t\t\tthrow new SocketException(\"Socket is not connected\");\n\t\t}\n\t\tif (isOutputShutdown()) {\n\t\t\tthrow new SocketException(\"Socket output is shutdown\");\n\t\t}\n\n\t\treturn Channels.newOutputStream(this.socketChannel);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/270dfe353fb830fd69b823a8a859287ff103854b/buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/socket/UnixDomainSocket.java#L47-L83","documentation":"The third state check in UnixDomainSocket.getInputStream: if isInputShutdown() is true, throw SocketException('Socket input is shutdown'). This mirrors java.net.Socket.shutdownInput() semantics — a half-close for the read direction. Once shutdownInput() has been called, the input stream cannot be obtained again on the same socket.","triggerScenarios":"getInputStream() is called after shutdownInput() was invoked on the socket (half-close for reading).","commonSituations":"A protocol layer that calls shutdownInput() after sending a request and then tries to read a response; reuse of a half-closed socket for a second request; test code invoking shutdownInput().","solutions":["Do not call shutdownInput() if further reads are needed on this socket.","Open a new socket (UnixDomainSocket.get(path)) for the next read."],"exampleFix":"// before\nsocket.shutdownInput();\nsocket.getInputStream().read(); // throws \"Socket input is shutdown\"\n// after: open a fresh socket for the next read\nSocket next = UnixDomainSocket.get(path);\nnext.getInputStream().read();","handlingStrategy":"validation","validationCode":"// Guard before obtaining a stream\nif (socket.isInputShutdown()) {\n    socket = UnixDomainSocket.get(path); // reopen for a fresh input stream\n}\nInputStream in = socket.getInputStream();","typeGuard":null,"tryCatchPattern":"try {\n    socket.getInputStream();\n} catch (java.net.SocketException ex) {\n    if (\"Socket input is shutdown\".equals(ex.getMessage())) {\n        socket = UnixDomainSocket.get(path); // reopen and retry once\n    } else throw ex;\n}","preventionTips":["Do not call shutdownInput() on sockets that need further reads.","Open a fresh socket per request/response cycle rather than reusing half-closed sockets.","Audit protocol implementations that half-close after sending for correctness."],"tags":["docker","socket","unix-domain-socket","buildpack"],"backgroundTag":null,"analyzedSha":"270dfe353fb830fd69b823a8a859287ff103854b","analyzedAt":"2026-08-11T19:42:06.541Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}