47

I was able to do sftp yesterday to a RHEL 5.4 box (RedHat) and today I can't.

The message is "Received message too long 778199411", and after some investigation, it was due to my RHEL box's .bashrc having a line echo "running .bashrc" -- or echoing anything at all, I think.

So why would printing out a line affect sftp? It felt a bit like a design issue as printing out a line in .bashrc works in other situations such as log in or ssh and it is kind of hard to track down when sftp fails for such a weird reason.

So the question is, why printing out a line cause such error and what if we still like to print out something in .bashrc? (mainly to see when this file gets sourced/executed).

nonopolarity
  • 2,969
  • 6
  • 31
  • 41
  • http://stackoverflow.com/questions/12440287/scp-doesnt-work-when-echo-in-bashrc – quanta May 21 '13 at 15:58
  • I had this problem after I had put some echo statements in various scripts in `/etc/profile.d` and in `~/.bashrc` to diagnose some other problem (which was: why is there a delay on ssh-ing into a remote server? Turns out it was because a script to ssh had `-Y` as an argument to `ssh` and was waiting for an X server on the client, which wasn't running) - anyway, rather than delete the echo statements I'd put in various login scripts, I wondered if echoing the messages to stderr instead of stdout would avoid the sftp error and it did, e.g. `>&2 echo "info: this is my_script.sh". Not enough rep! – drkvogel Dec 29 '20 at 01:36
  • If you have your custom scripts in the `~/.bashrc` just comment those. – Mohan Jan 20 '23 at 06:49

6 Answers6

52

This is a longstanding problem. I found it ten years ago when I first had to mix commercial SSH at work and open-SSH at home. I ran into it again today and found this post.

If I had searched for "sftp/scp fails but ssh is OK" I would have been reminded of the solution sooner!

Put simply, .bashrc, .bash_profile, .cshrc, .profile, etc., have to be silent for non-interactive sessions or they interfere with the sftp / scp connection protocol. 

This output confuses the sftp/scp client.  You can verify if your shell is doing this by executing:
    ssh yourhost /usr/bin/true
    If the above command produces any output, then you need to modify your shell initialization.

    From the open-SSH FAQ: 2.9 - sftp/scp fails at connection, but ssh is OK.

    Peter Scott
    • 629
    • 5
    • 3
    • Self-updating shell utilities are a good culprits for this problem. For me it has often been Ruby Version manager interfering with Jenkins' deploy-over-ssh. – Eric P. Sep 03 '14 at 13:33
    • Thanks for this, removing some debugging echo statements I had in my bashrc and bash_profile solved this for me. – SgtPooki Nov 14 '14 at 18:56
    • 4
      Wrong .bashrc needs to be silent, .bash_profile can echo with no problems. – kubanczyk Dec 13 '15 at 22:52
    • 4
      For anyone landing here: As suggested in https://serverfault.com/a/630714, you can use `ssh yourhost /usr/bin/true` to probe the output of your ssh. In my case, I found some command in ~/.bashrc started to produce errors. – Yuval Atzmon May 29 '17 at 11:22
    • If only I could give more than one vote for a post. This is a beautiful piece of knowledge - how I've not hit it in 30 years of *nix is a lucky thing I spose. – volvox Aug 02 '23 at 22:19
    33

    At least for SFTP this can be fixed by using the internal-sftp subsystem, as that does not read .bashrc or /etc/motd.

    Simply change the /etc/ssh/sshd_config file and change the SFTP subsystem:

    #Subsystem sftp /usr/lib/openssh/sftp-server
    Subsystem sftp internal-sftp
    

    And the error is gone.

    Kenneth
    • 439
    • 4
    • 3
    • I like this one.. just wonder if this has any security implications? – RoyM Feb 08 '17 at 18:57
    • `internal-sftp` is, IMO, a better way to offer SFTP support. You can see this related post: https://serverfault.com/questions/660160/openssh-difference-between-internal-sftp-and-sftp-server – Kenneth Feb 09 '17 at 21:04
    • After your sshd_config change suggestion, I killed sshd and sftp (not sure if there was a demon). First time got the Received Message too long error but was logged in anyway. Then back to the same problem – clearlight Oct 23 '17 at 01:01
    • Thanks, this is the only way I've found to have enabled sftp, ssh and X forwarding in my server for the same user. – Miguel Ortiz Feb 13 '20 at 14:31
    11

    just put following into top of ~/.bashrc on username of id on remote machine if that id uses bash

    # If not running interactively, don't do anything and return early
    [[ $- == *i* ]] || return  
    

    which simply exits early from the ~/.bashrc instead of sourcing entire file ... this solves making .bashrc silent when you are not logging into that id and are just running your scp or sftp with that username as the remote id ... to quote @Peter Scott in other answer : "Put simply, .bashrc and .bash_profile etc have to be silent or they interfere with the sftp / scp connection protocol."

    Alternatively, if that remote id uses zsh then put following at top of its ~/.zshrc

    # If not running interactively, don't do anything and return early
    [[ -o interactive ]] || exit 0
    

    If the shell on your remote machine does not use ~/.bashrc then make above edit in file ~/.bashrc_profile or ~/.profile or similar to suit your shell on that remote box

    .... UPDATE ... by putting above snippet into top of file ~/.bashrc for user on remote box any ssh connection will source file ~/.bashrc which will simply read ~/.bashrc until is sees this snippet then stop continuing to source the remainder of file ~/.bashrc so as to avoid polluting the shell on that remote box with things ssh connection does not need nor want ... do NOT put snippet into any file which must get sourced or executed to completion as the point of this snippet is to exit early from sourcing file ~/.bashrc ( NOTE there is a difference between sourcing a file versus executing a file ) ... file ~/.bashrc is always sourced never executed

    Scott Stensland
    • 2,673
    • 2
    • 25
    • 24
    • This worked for me. Kenneth's answer to use the `internal-sftp` subsystem would only work if you have root access. Where I work that is not the case. – John Jan 24 '20 at 12:20
    • Watch out people! After adding this command I was unable to ssh to my server at all! SSH immediately disconnects you! – Marc Jan 04 '22 at 13:28
    • @Marc I have above snippet in production on all my boxes who all use bash no problems ... assure you copy exactly as is ... note the - sign as in `$-` do not leave that out – Scott Stensland Jan 04 '22 at 14:20
    • I am also using your exact code on CentOS7 - I can again confirm it kills ssh. The connection is successful and then you are disconnected. I placed your code in `/etc/profile.d/ansible.sh`. – Marc Jan 04 '22 at 15:45
    • @Marc please see my UPDATE note – Scott Stensland Jan 04 '22 at 19:26
    • Thanks for the clarification. However, I have moved the command to my users `~/.bashrc` with the exact same effect - it kills ssh. – Marc Jan 05 '22 at 07:40
    • very good to provide resolution. – rajeev Mar 17 '22 at 03:14
    4

    Every response I've seen anywhere on this all claim it is too much printed output via /etc/motd, or .bashrc, etc. Not always true. If you have an account that has no .bashrc, the /etc/motd is empty, and the default .bashrc is minimal with no printed output YOU CAN STILL have the problem. If you have a user account with a shell of /sbin/nologin or /bin/false this error will still happen.

    Why would you do this??? If you were trying to grant someone root-jailed sftp, with no secure-shell access this will happen.

    Work around: allow ssh and put them in a root jail as well. This is a problem that needs to be addressed in ssh, it's far too long in coming.

    Jakuje
    • 20,974
    • 7
    • 51
    • 70
    TekOps
    • 71
    • 2
    • I had this problem exactly because of too long custom output in my .bashrc (I have screenfetch there). But I still trying to figure out how to make it ignore this – vladkras Aug 11 '16 at 12:16
    • Yes, that could be the case. You have to modify ssh. In our case it was a problem with the shell. We actually used an sftp client specifically for root-jail so didn't have to do all the root-jail stuff. – TekOps Aug 12 '16 at 16:11
    • The point is I don't want to modify my .bashrc. I want to connect to server with any length of first message. So I do have to modify settings of my IDE probably – vladkras Aug 15 '16 at 13:56
    2

    There can be one more reason. On RHEL 6 with openssh-5.3p1-122.el6.x86_64 we have found, that it behaves wrong when LOCALE remains at "C". When changed with:

    export LC_ALL="en_US.UTF-8"
    

    Then sftp behaves correctly. In the previous openssh-5.3p1-118 we haven't experienced such a behaviour so it's probably some minor bug in this build.

    Jaroslav Kucera
    • 9,422
    • 5
    • 15
    • 28
    0

    In my case, to make it work, I needed to disable Ubuntu's welcome message.

    Stephen Rauch
    • 4,209
    • 14
    • 22
    • 32
    Walty Yeung
    • 101
    • 2