diff --git a/changelog/unreleased/issue-2591 b/changelog/unreleased/issue-2591
new file mode 100644
index 000000000..04ca6f67a
--- /dev/null
+++ b/changelog/unreleased/issue-2591
@@ -0,0 +1,22 @@
+Bugfix: Don't read password from stdin for backup --stdin
+
+Restic backup previously tried to read first the password, then the data
+to be backed up from standard input. This meant it would often confuse part
+of the data for the password.
+
+From now on, restic backup --stdin will exit with the message
+
+    Fatal: cannot read both password and data from stdin
+
+unless the password is passed in some other way (--restic-password-file,
+RESTIC_PASSWORD, etc.). To enter the password interactively, a password
+command has to be used. For example, on Linux,
+
+    mysqldump somedatabase |
+        restic backup --stdin \
+            --password-command='sh -c "systemd-ask-password < /dev/tty"'
+
+securely reads the password from the terminal.
+
+https://github.com/restic/restic/issues/2591
+https://github.com/restic/restic/pull/4011
diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go
index 327c0defc..8b1f13b55 100644
--- a/cmd/restic/cmd_backup.go
+++ b/cmd/restic/cmd_backup.go
@@ -262,6 +262,10 @@ func readFilenamesRaw(r io.Reader) (names []string, err error) {
 // Check returns an error when an invalid combination of options was set.
 func (opts BackupOptions) Check(gopts GlobalOptions, args []string) error {
 	if gopts.password == "" {
+		if opts.Stdin {
+			return errors.Fatal("cannot read both password and data from stdin")
+		}
+
 		filesFrom := append(append(opts.FilesFrom, opts.FilesFromVerbatim...), opts.FilesFromRaw...)
 		for _, filename := range filesFrom {
 			if filename == "-" {