Environment
- OS: Windows 11 Enterprise, Version 25H2, Build 26200.8655
- SQLcl Version: 26.1.2.0 Production (Build 26.1.2.132.1334)
- JDK: Oracle JDK 21.0.11+9-LTS-211 (also reproduced on JDK 17.0.9)
- Claude Desktop: MSIX package, Version 1.14271.0.0
- Winsock AF_UNIX: Present and registered (
netsh winsock show catalog confirms two AF_UNIX entries)
- AFUnix kernel driver: Running (
sc query afunix confirms STATE: RUNNING)
Description
When SQLcl 26.1.2 is launched with the -mcp flag (Model Context Protocol server mode) on Windows 11, it crashes immediately during startup with a java.io.UncheckedIOException: Unable to establish loopback connection originating from SDKSManager initialization.
The MCP server prints the startup banner and begins processing the MCP initialize handshake from the client, but then crashes before completing initialization, disconnecting the transport.
Full Stack Trace
Exception in thread "main" java.io.UncheckedIOException: java.io.IOException: Unable to establish loopback connection
at java.net.http/jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:328)
at java.net.http/jdk.internal.net.http.HttpClientImpl.create(HttpClientImpl.java:270)
at java.net.http/jdk.internal.net.http.HttpClientBuilderImpl.build(HttpClientBuilderImpl.java:135)
at oracle.dbtools.sdks.installer.commands.SDKSManager.<init>(SDKSManager.java:61)
at oracle.dbtools.sdks.installer.commands.SDKSCommand.<init>(SDKSCommand.java:29)
at oracle.dbtools.raptor.newscriptrunner.CommandRegistry.addListener(CommandRegistry.java:291)
at oracle.dbtools.raptor.newscriptrunner.CommandRegistry.addForAllStmtsListener(CommandRegistry.java:256)
at oracle.dbtools.extension.SQLCLServices.registerServices(SQLCLServices.java:50)
at oracle.dbtools.mcp.container.McpStdioContainer.<init>(McpStdioContainer.java:37)
at oracle.dbtools.mcp.container.McpStdioContainer$Builder.newContainer(McpStdioContainer.java:95)
at oracle.dbtools.mcp.container.McpStdioContainer$Builder.newContainer(McpStdioContainer.java:80)
at oracle.dbtools.mcp.api.Mcp$Stdio$Builder.build(Mcp.java:141)
at oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli.main(SqlCli.java:342)
Caused by: java.io.IOException: Unable to establish loopback connection
at java.base/sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:101)
at java.base/sun.nio.ch.PipeImpl.<init>(PipeImpl.java:195)
at java.base/sun.nio.ch.WEPollSelectorImpl.<init>(WEPollSelectorImpl.java:78)
at java.base/sun.nio.ch.WEPollSelectorProvider.openSelector(WEPollSelectorProvider.java:33)
at java.base/java.nio.channels.Selector.open(Selector.java:295)
at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.<init>(HttpClientImpl.java:721)
at java.net.http/jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:325)
Caused by: java.net.SocketException: Invalid argument: connect
at java.base/sun.nio.ch.UnixDomainSockets.connect0(Native Method)
at java.base/sun.nio.ch.UnixDomainSockets.connect(UnixDomainSockets.java:148)
at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:851)
at java.base/java.nio.channels.SocketChannel.open(SocketChannel.java:285)
at java.base/sun.nio.ch.PipeImpl$Initializer$LoopbackConnector.run(PipeImpl.java:131)
at java.base/sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:83)
Root Cause Analysis
SDKSManager unconditionally constructs a java.net.http.HttpClient during MCP container initialization. On Windows, the JVM's HttpClient internally instantiates a WEPollSelectorImpl, which creates a PipeImpl for its internal event pipe. PipeImpl on Windows attempts a Unix domain socket loopback connection via UnixDomainSockets.connect0 (a native JNI call), which fails with Invalid argument: connect (Windows error WSAEINVAL).
This failure is unconditional — it occurs regardless of:
- JDK version (reproduced on both JDK 17.0.9 and JDK 21.0.11 LTS)
- JVM flags attempted:
-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider, -Djdk.net.usePlainSocketImpl=true, -Doracle.dbtools.sdks.enabled=false, and others
- Winsock catalog state (AF_UNIX present and registered,
afunix kernel driver running)
- Whether the process is launched directly or via a wrapper batch file
- MSIX sandbox presence
The crash does not occur when SQLcl -mcp is launched interactively from a command prompt with JAVA_TOOL_OPTIONS set, where it starts and waits correctly for MCP JSON input. The failure is specific to the process launch environment created by MCP client hosts (Claude Desktop) which pipe stdio to the SQLcl process.
Steps to Reproduce
- Install SQLcl 26.1.2 on Windows 11
- Configure an MCP client (e.g., Claude Desktop) to launch
sql -mcp
- Start the MCP client
- Observe SQLcl crash on every connection attempt
Alternatively, reproduce from command line by piping stdin:
cmd
echo {} | D:\Oracle\sqlcl\bin\sql -mcp
Expected Behavior
SQLcl MCP server starts and remains running, processing MCP JSON-RPC messages over stdio, consistent with behavior on macOS and Linux.
Actual Behavior
SQLcl MCP server crashes immediately after printing the startup banner, before completing the MCP handshake.
Suggested Fix
SDKSManager should not unconditionally instantiate HttpClient during MCP container initialization on all platforms. Either:
- Defer
HttpClient construction until it is actually needed (lazy initialization)
- Guard the
SDKSManager registration behind a platform capability check
- Use a TCP-based pipe fallback instead of Unix domain socket loopback on Windows
Impact
SQLcl MCP integration is completely non-functional on Windows. This blocks Oracle APEX and Oracle DB developers from using SQLcl as an MCP server with AI-assisted development tools such as Claude Desktop, which is the primary advertised use case for sql -mcp.