diff --git a/changelog/unreleased/issue-2152 b/changelog/unreleased/issue-2152
new file mode 100644
index 000000000..25492e5ed
--- /dev/null
+++ b/changelog/unreleased/issue-2152
@@ -0,0 +1,11 @@
+Enhancement: only open connection once for `init` command using sftp backend
+
+The `init` command using the sftp backend used to connect twice to the
+repository. This can be inconvenient if the user must enter a password or cause
+`init` to fail if the server does not correctly close the first sftp
+connection.
+
+This has been fixed by reusing the initial sftp connection.
+
+https://github.com/restic/restic/issues/2152
+https://github.com/restic/restic/pull/3882
diff --git a/internal/backend/sftp/sftp.go b/internal/backend/sftp/sftp.go
index 0aa2700a6..a1b8f5cdf 100644
--- a/internal/backend/sftp/sftp.go
+++ b/internal/backend/sftp/sftp.go
@@ -44,7 +44,12 @@ var _ restic.Backend = &SFTP{}
 
 const defaultLayout = "default"
 
-func startClient(program string, args ...string) (*SFTP, error) {
+func startClient(cfg Config) (*SFTP, error) {
+	program, args, err := buildSSHCommand(cfg)
+	if err != nil {
+		return nil, err
+	}
+
 	debug.Log("start client %v %v", program, args)
 	// Connect to a remote host and request the sftp subsystem via the 'ssh'
 	// command.  This assumes that passwordless login is correctly configured.
@@ -121,22 +126,21 @@ func (r *SFTP) clientError() error {
 func Open(ctx context.Context, cfg Config) (*SFTP, error) {
 	debug.Log("open backend with config %#v", cfg)
 
-	sem, err := sema.New(cfg.Connections)
-	if err != nil {
-		return nil, err
-	}
-
-	cmd, args, err := buildSSHCommand(cfg)
-	if err != nil {
-		return nil, err
-	}
-
-	sftp, err := startClient(cmd, args...)
+	sftp, err := startClient(cfg)
 	if err != nil {
 		debug.Log("unable to start program: %v", err)
 		return nil, err
 	}
 
+	return open(ctx, sftp, cfg)
+}
+
+func open(ctx context.Context, sftp *SFTP, cfg Config) (*SFTP, error) {
+	sem, err := sema.New(cfg.Connections)
+	if err != nil {
+		return nil, err
+	}
+
 	sftp.Layout, err = backend.ParseLayout(ctx, sftp, cfg.Layout, defaultLayout, cfg.Path)
 	if err != nil {
 		return nil, err
@@ -230,12 +234,7 @@ func buildSSHCommand(cfg Config) (cmd string, args []string, err error) {
 // Create creates an sftp backend as described by the config by running "ssh"
 // with the appropriate arguments (or cfg.Command, if set).
 func Create(ctx context.Context, cfg Config) (*SFTP, error) {
-	cmd, args, err := buildSSHCommand(cfg)
-	if err != nil {
-		return nil, err
-	}
-
-	sftp, err := startClient(cmd, args...)
+	sftp, err := startClient(cfg)
 	if err != nil {
 		debug.Log("unable to start program: %v", err)
 		return nil, err
@@ -259,13 +258,8 @@ func Create(ctx context.Context, cfg Config) (*SFTP, error) {
 		return nil, err
 	}
 
-	err = sftp.Close()
-	if err != nil {
-		return nil, errors.Wrap(err, "Close")
-	}
-
-	// open backend
-	return Open(ctx, cfg)
+	// repurpose existing connection
+	return open(ctx, sftp, cfg)
 }
 
 func (r *SFTP) Connections() uint {