restic/restic · error

ReadPassword: %w

Error message

ReadPassword: %w

What it means

The interactive password prompt called term.ReadPassword on the terminal and it failed. This is terminal-layer I/O: stdin is not a real terminal (raw-mode ioctl fails), the tty was closed, or the read was interrupted. The function has already restored terminal state and cancelled cleanly on ctx.Done; this branch is a hard read failure.

Source

Thrown at internal/terminal/password.go:50

		if err != nil {
			return
		}
		_, err = fmt.Fprintln(out)
	}()

	select {
	case <-ctx.Done():
		err := term.Restore(inFd, state)
		if err != nil {
			_, _ = fmt.Fprintf(out, "unable to restore terminal state: %v\n", err)
		}
		return "", ctx.Err()
	case <-done:
		// clean shutdown, nothing to do
	}

	if err != nil {
		return "", fmt.Errorf("ReadPassword: %w", err)
	}

	return string(buf), nil
}

View on GitHub (pinned to a80be1478a)

Solutions

  1. Provide the password non-interactively: --password-file, RESTIC_PASSWORD_FILE, or RESTIC_PASSWORD
  2. For scripted stdin use: restic backup ... < pwfile (termstatus reads a line when not a tty)
  3. Allocate a tty when interactivity is intended: ssh -t, docker run -it
  4. Ensure /dev/tty exists and is usable in the execution context (containers, chroots)

Example fix

# before (cron job, no tty)
restic backup /data
# Error: ReadPassword: inappropriate ioctl for device

# after
echo 's3cret' > /etc/restic/pw && chmod 600 /etc/restic/pw
RESTIC_PASSWORD_FILE=/etc/restic/pw restic backup /data
Defensive patterns

Strategy: validation

Validate before calling

// decide the password source up front; never rely on an interactive prompt
if os.Getenv("RESTIC_PASSWORD_FILE") == "" && os.Getenv("RESTIC_PASSWORD") == "" {
    if !term.IsTerminal(int(os.Stdin.Fd())) {
        return errors.New("no tty and no password configured; set RESTIC_PASSWORD_FILE")
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "ReadPassword:") {
    // switch strategy: read from --password-file / env var instead of tty
}

Prevention

When it happens

Trigger: Running restic where stdin is a pipe/file rather than a tty and no password source is configured; running under a service manager/cron with no controlling terminal; ssh session dropped mid-prompt; a closed /dev/tty.

Common situations: Scripts/CI calling restic interactively; Docker run without -t; cron jobs or systemd services without password configuration; double-bg session detaching the tty.

Related errors


AI-assisted analysis of restic/restic@a80be1478a (2026-08-15). Data as JSON: /api/errors/024b7d80dcdc4de6. Report an issue: GitHub.