{"record":{"id":"80a493113c0731d6","repo":"jenkinsci/jenkins","slug":"failed-to-retrieve-command-result-in-time","errorCode":null,"errorMessage":"Failed to retrieve command result in time: {}","messagePattern":"Failed to retrieve command result in time: (.+?)","errorType":"exception","errorClass":"SocketTimeoutException","httpStatus":null,"severity":"error","filePath":"cli/src/main/java/hudson/cli/SSHCLI.java","lineNumber":113,"sourceCode":"            cf.await();\n            try (ClientSession session = cf.getSession()) {\n                for (KeyPair pair : provider.getKeys()) {\n                    CLI.LOGGER.log(FINE, \"Offering {0} private key\", pair.getPrivate().getAlgorithm());\n                    session.addPublicKeyIdentity(pair);\n                }\n                session.auth().verify(10000L);\n\n                try (ClientChannel channel = session.createExecChannel(command.toString())) {\n                    channel.setIn(new NoCloseInputStream(System.in));\n                    channel.setOut(new NoCloseOutputStream(System.out));\n                    channel.setErr(new NoCloseOutputStream(System.err));\n                    WaitableFuture wf = channel.open();\n                    wf.await();\n\n                    Set<ClientChannelEvent> waitMask = channel.waitFor(List.of(ClientChannelEvent.CLOSED), 0L);\n\n                    if (waitMask.contains(ClientChannelEvent.TIMEOUT)) {\n                        throw new SocketTimeoutException(\"Failed to retrieve command result in time: \" + command);\n                    }\n\n                    Integer exitStatus = channel.getExitStatus();\n                    return exitStatus;\n\n                }\n            } finally {\n                client.stop();\n            }\n        }\n    }\n\n    @SuppressFBWarnings(value = \"URLCONNECTION_SSRF_FD\", justification = \"Client-side code doesn't involve SSRF.\")\n    private static URLConnection openConnection(URL url) throws IOException {\n        return url.openConnection();\n    }\n\n    private SSHCLI() {}","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/cli/src/main/java/hudson/cli/SSHCLI.java#L95-L131","documentation":"SocketTimeoutException thrown by SSHCLI when channel.waitFor(ClientChannelEvent.CLOSED, 0L) returns a mask containing TIMEOUT. The SSH exec channel did not close within the wait, so no exit status could be obtained for the command.","triggerScenarios":"The remote Jenkins SSH command hangs (long-running operation, waiting on a lock, or prompting for input that never arrives), or the network stalls so the channel never receives EOF/CLOSED.","commonSituations":"Running a CLI command that triggers a long job/lock on the controller; SSH keepalive not configured so a dead connection lingers; command blocked on stdin that the client never sends/closes.","solutions":["Confirm the command is expected to terminate; if it is long-running, run it asynchronously or increase the effective timeout.","Ensure stdin is closed/redirected (</dev/null) so the remote command does not block waiting for input.","Check SSH/network health and that the controller is responsive (not GC-thrashing or deadlocked)."],"exampleFix":"# before: command may block on stdin\njava -jar jenkins-cli.jar -ssh -s jenkins help\n# after: close stdin so the channel can terminate\necho '' | java -jar jenkins-cli.jar -ssh -s jenkins help\n# or: java -jar jenkins-cli.jar -ssh -s jenkins help </dev/null","handlingStrategy":"retry","validationCode":"// Before running, sanity-check the controller is responsive over SSH\ntry (ClientSession s = client.connect(UserAuth, host, port).verify(10, TimeUnit.SECONDS).getSession()) {\n    s.auth().verify(10000L);\n} // reachable; proceed to run the command","typeGuard":null,"tryCatchPattern":"try {\n    channel.waitFor(List.of(ClientChannelEvent.CLOSED), timeout);\n} catch (SocketTimeoutException e) {\n    // optionally retry once, then report the command did not finish in time\n}","preventionTips":["Close stdin (</dev/null) for commands that do not need input.","Use non-blocking CLI invocations for long-running operations.","Configure SSH keepalives to detect dead connections faster."],"tags":["jenkins-cli","ssh","timeout","channel"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}