Ben Moskovitz
Ben Moskovitz

Reputation: 31

Net::SFTP::Session can't run stat, apparently has a Nil channel

So I have some code that checks if there's a certain file on remote SFTP server:

def size
    adapter.sftp.stat(path).size
end

where sftp is a Net::SFTP::Session object defined in this case as

@sftp = Net::SFTP.start(host, username, password: password)

and path is the file path to the object that I want to call stat() on.

Unfortunately, when I try to excecute this code, I get this error:

NoMethodError:
   undefined method `send_data' for nil:NilClass
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:814:in `send_packet'
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/protocol/base.rb:45:in `send_request'
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/protocol/01/base.rb:90:in `open'
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:830:in `request'
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:182:in `open'
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:191:in `open!'
 # /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/operations/file_factory.rb:40:in `open'
 # /Users/Ben/remote_filesystem/lib/remote_filesystem/path/sftp.rb:46:in `size'
 # ./sftp_spec.rb:72:in `block (3 levels) in <top (required)>'

As far as I can tell from looking at the source code for Net::SFTP::Session, on line 814 of session.rb, channel.send_data is called, but apparently my SFTP Session has a Nil channel for some reason. Can anyone explain how to fix this issue?

Upvotes: 2

Views: 1155

Answers (2)

Misha
Misha

Reputation: 91

As mentioned earlier, it means your SFTP session is terminated.

Check TCP logs (wireshark is your friend), the session may be terminated by the peer in the meantime.

A case when such error is happening is if you are doing write(data) operation with data length that exceeds TCP window size on the receiving side. A fix would be to repeat write operations with a buffer, like

  io = StringIO.new(data)
  sftp_session.file.open(filename, "w") do |file|
    while buffer = io.read(BUFFER_SIZE)
      file.write(buffer)
    end
  end

Upvotes: 0

Alex Altair
Alex Altair

Reputation: 3715

If you're caching sftp, the cache might have been invalidated. I came across this exception, because I had tried to call ftp.file.open on an ftp connection that was no longer open.

Upvotes: 0

Related Questions