hierynomus / hierynomus/sshj

"Opening `session` channel failed: open failed" exception when running multiple commands in succession

Open
#749 6 comments 1 reaction 0 assignees View on GitHub
Dominant language
Java
Stars
2.7k
Forks
620
Avg merge
3d 23h
Merged PRs (30d)
11

Description

Found this bug while trying out 0.32.0 - 0.31.0 still works.
Assuming reusing sshClient for multiple commands is a legitimate use case.
Distilled it to the following code snippet that reliably reproduces the above exception:
```
Session sshSession;
Session.Command sshCommand;
logger.log(Level.INFO,"calling exec in quick succession 1");
// sshClient intialized further back.
sshSession=sshClient.startSession();
logger.log(Level.INFO,"started session 1, echoing");
sshCommand = sshSession.exec("echo hello");
logger.log(Level.INFO,"echoed, reading");
// Intended for result logging and error handling.
// Using net.schmizz.sshj.common.IOUtils.readFully behaves the same
org.apache.commons.io.IOUtils.toString(sshCommand.getInputStream());
logger.log(Level.INFO,"read, closing");
sshSession.close();
//Thread.sleep(1000); // Workaround.
logger.log(Level.INFO,"calling exec in quick succession 2");
sshSession=sshClient.startSession(); // failure
logger.log(Level.INFO,"started session 2, echoing");
sshSession.exec("echo hello");
logger.log(Level.INFO,"echoed, closing");
sshSession.close();
```
Short version:
```
sshSession=sshClient.startSession();
sshCommand = sshSession.exec("echo hello");
org.apache.commons.io.IOUtils.toString(sshCommand.getInputStream());
sshSession.close();

sshSession=sshClient.startSession();
sshSession.exec("echo hello");
sshSession.close();
```

The log output (sanitized) will show the following:
```
calling exec in quick succession 1
started session 1, echoing
echoed, reading
read, closing
calling exec in quick succession 2
Exception: open failed
...
Caused by: Opening `session` channel failed: open failed
at net.schmizz.sshj.connection.channel.direct.AbstractDirectChannel.gotOpenFailure(AbstractDirectChannel.java:74)
at net.schmizz.sshj.connection.channel.direct.AbstractDirectChannel.gotUnknown(AbstractDirectChannel.java:99)
at net.schmizz.sshj.connection.channel.AbstractChannel.handle(AbstractChannel.java:204)
at net.schmizz.sshj.connection.ConnectionImpl.handle(ConnectionImpl.java:130)
at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:472)
at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:113)
at net.schmizz.sshj.transport.Decoder.received(Decoder.java:200)
at net.schmizz.sshj.transport.Reader.run(Reader.java:60)

```
So the program will fail at starting session right after the previous one closed.
I've confirmed that commenting out `org.apache.commons.io.IOUtils.toString(sshCommand.getInputStream());` will fix the issue.
I've also found that inserting a `Thread.sleep(1000)` after the session close fixes the issue.

I've checked the recent SSHJ changes and found commit eb09a16 (Send EOF on channel Close).
I've reverted that commit, rebuilt SSHJ and re-run the test and it worked.

I don't understand the code well enough to tell you why the revert worked (it really shouldn't) or why the sleep worked (it really, REALLY shouldn't) or to suggest an actual solution, but the above should be reproducible.
This one is going on the shelf with the "weird damn bugs".

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.