{"record":{"id":"7006e289ad802fb8","repo":"juicedata/juicefs","slug":"couldn-t-initialise-sftp","errorCode":null,"errorMessage":"couldn't initialise SFTP","messagePattern":"couldn't initialise SFTP","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/sftp.go","lineNumber":95,"sourceCode":"\n// Open a new connection to the SFTP server.\nfunc (f *sftpStore) sftpConnection() (c *conn, err error) {\n\tc = &conn{\n\t\terr: make(chan error, 1),\n\t}\n\tconn, err := net.Dial(\"tcp\", net.JoinHostPort(f.host, f.port))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsshc, chans, reqs, err := ssh.NewClientConn(conn, net.JoinHostPort(f.host, f.port), f.config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.sshClient = ssh.NewClient(sshc, chans, reqs)\n\tc.sftpClient, err = sftp.NewClient(c.sshClient)\n\tif err != nil {\n\t\t_ = c.sshClient.Close()\n\t\treturn nil, errors.Wrap(err, \"couldn't initialise SFTP\")\n\t}\n\tgo c.wait()\n\treturn c, nil\n}\n\n// Get an SFTP connection from the pool, or open a new one\nfunc (f *sftpStore) getSftpConnection() (c *conn, err error) {\n\tf.poolMu.Lock()\n\tfor len(f.pool) > 0 {\n\t\tc = f.pool[0]\n\t\tf.pool = f.pool[1:]\n\t\terr := c.closed()\n\t\tif err == nil {\n\t\t\tbreak\n\t\t}\n\t\tc = nil\n\t}\n\tf.poolMu.Unlock()","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/sftp.go#L77-L113","documentation":"Raised by sftpConnection in pkg/object/sftp.go:95. After a successful SSH handshake, the client attempts sftp.NewClient(sshClient), which requests the \"sftp\" subsystem over the SSH connection. If the server does not run an SFTP subsystem (or the handshake with that subsystem fails), the SSH client is closed and this wrapped error is returned. It indicates the SSH endpoint is not SFTP-capable, not a network failure per se.","triggerScenarios":"Creating an SFTP object store where the remote sshd has no \"Subsystem sftp\" configured, the sftp-server binary is missing, the user's shell/subsystem is restricted (e.g. forced internal-sftp with wrong path, or rssh/nologin shell), or the server rejects the subsystem request.","commonSituations":"Minimal container/SSH servers without openssh-sftp-server installed; hardened sshd_config with Subsystem removed; restricted SFTP chroot setups that reject the client; connecting to a non-OpenSSH server lacking SFTP support.","solutions":["Enable the SFTP subsystem on the server: add 'Subsystem sftp internal-sftp' (or the sftp-server binary path) to sshd_config and reload sshd.","Verify manually with: printf 'version\\n' | sftp user@host (or ssh -s sftp user@host) to confirm the subsystem is offered.","Confirm the sftp-server binary exists on the server (e.g. /usr/lib/openssh/sftp-server) if using an explicit Subsystem path.","Check the user account is not restricted to a shell (nologin/rssh) that blocks subsystem requests.","Inspect the wrapped underlying error for the precise server rejection reason."],"exampleFix":"// server side: /etc/ssh/sshd_config\n// before\n#Subsystem sftp /usr/lib/openssh/sftp-server\n\n// after\nSubsystem sftp internal-sftp\n// then: systemctl reload sshd","handlingStrategy":"validation","validationCode":"// Check SFTP subsystem availability before configuring the store\nconn, err := ssh.Dial(\"tcp\", host, sshCfg)\nif err != nil { return err }\nsess, err := conn.NewSession()\nif err != nil { return err }\nerr = sess.RequestSubsystem(\"sftp\")\nsess.Close()\nconn.Close()\nif err != nil {\n    return fmt.Errorf(\"host %s does not provide the sftp subsystem: %w\", host, err)\n}","typeGuard":null,"tryCatchPattern":"c, err := getSftpConnection(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"couldn't initialise SFTP\") {\n        // server lacks sftp subsystem: surface a clear config hint to the operator\n    }\n    return err\n}","preventionTips":["Enable 'Subsystem sftp internal-sftp' on every SSH server used as an SFTP backend.","Smoke-test with `ssh -s sftp user@host` during provisioning.","Use non-restricted accounts (avoid nologin/rssh) for SFTP backends.","Document required openssh-sftp-server package for container images."],"tags":["sftp","ssh","network","configuration","subsystem"],"backgroundTag":"connection-refused","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}