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
- Provide the password non-interactively: --password-file, RESTIC_PASSWORD_FILE, or RESTIC_PASSWORD
- For scripted stdin use: restic backup ... < pwfile (termstatus reads a line when not a tty)
- Allocate a tty when interactivity is intended: ssh -t, docker run -it
- 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
- Always set RESTIC_PASSWORD_FILE in scripts, cron, containers
- Use ssh -t / docker -it when interactive prompting is intended
- Smoke-test automation with an empty environment to catch tty assumptions
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.