sudo: no tty present and no askpass program specified

Fix sudo: no tty present and no askpass program specified

Cron jobs and CI scripts crash with this sudo error because there's no terminal for the password prompt. Here's the real fix and why it works.

You wrote a script, it works fine when you run it in your terminal, then you move it to cron or a CI pipeline and it explodes with sudo: no tty present and no askpass program specified. Annoying, and the error message doesn't exactly explain itself.

The error means exactly what it says: sudo wants to prompt you for a password, but there's no terminal attached to prompt through, and no askpass helper available to pop up a GUI dialog. Sudo can't ask, so it gives up.

The real fix is to stop sudo from needing to ask. You do that by granting passwordless sudo for the specific commands your script runs — and nothing else.

Step 1: Open sudoers safely with visudo

Never edit /etc/sudoers directly with nano or vim. A syntax error locks you out of sudo entirely, and recovering from that is a bad afternoon. Use visudo, which validates the file before saving.

sudo visudo

You should see the sudoers file open in your default editor. On Ubuntu 22.04 that's usually nano. Scroll to the bottom — do not touch the top section.

Step 2: Add a NOPASSWD rule for the user and commands

Say your cron job runs as user deploy and needs to restart nginx and run a systemctl reload. Add a line like this at the very bottom:

deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl reload nginx

Save and exit. In nano that's Ctrl+O, Enter, then Ctrl+X. You should land back at your shell prompt with no error output. If you see a parse error, visudo caught it and you can fix the line right there.

Now test from a non-interactive shell:

sudo -u deploy sudo -n systemctl reload nginx

The -n flag tells sudo "don't prompt, just fail if you'd need to." If that command runs clean, your cron job will too.

Step 3: If you need a blanket rule (and why you probably don't)

Some people slap this in and move on:

deploy ALL=(ALL) NOPASSWD: ALL

That works. It also means the deploy user can run literally anything as root with no password. If that user account gets compromised through a leaked SSH key or a bad container image, your box is gone. I've seen this exact shortcut turn a minor web app RCE into full root on a production database server. List the specific binaries you need, with full paths.

Why this works

Sudo has three ways to get a password: a TTY, an askpass program (GUI or SSH_ASKPASS), or nothing because it doesn't need one. Cron runs with no TTY at all — the process has no controlling terminal, so sudo's normal prompt fails. CI runners, systemd services, and Docker containers have the same problem.

NOPASSWD removes the password requirement for the listed commands, so sudo never tries to prompt. The command executes, the script continues, and the error is gone. It's not a hack around the error — it's sudo doing what it's designed to do for automation.

Less common variations

requiretty is set globally. Older RHEL and CentOS installs (RHEL 6, some 7 configs) ship with Defaults requiretty in sudoers. Even with NOPASSWD, sudo refuses to run without a TTY. Check with sudo grep -i requiretty /etc/sudoers. If it's there, either remove it or override it per-user:

Defaults:deploy !requiretty

You actually want an interactive prompt. If the script is running under SSH and you want a password prompt to reach the user, set up SSH_ASKPASS. Create a script that echoes the password (yes, this is insecure, use it only for controlled environments), then:

export SUDO_ASKPASS=/usr/local/bin/askpass.sh
sudo -A systemctl restart nginx

Passwordless via stdin. If you're stuck and can't edit sudoers, you can pipe the password in with -S:

echo "$SUDO_PASS" | sudo -S systemctl restart nginx

The password ends up in shell history, process lists, and logs. Only use this in throwaway containers where you don't care.

Wrong sudoers syntax causes a silent failure. Confirm your rule actually applies by running sudo -l -U deploy as root. You'll see a list of allowed commands. If your NOPASSWD rule isn't in that list, sudo never saw it — check for a typo, wrong user, or a rule above yours that matches first. Sudo applies the last matching rule, so ordering matters.

Prevention

  • Use sudo -n in your test scripts. It fails fast if a password would be needed, so you catch the problem on your laptop instead of at 3 AM when a cron job goes silent.
  • Create a dedicated service account for automation. Don't give cron root access via your personal user — if your account is revoked or its password rotates, you'll break jobs you forgot existed.
  • Keep a copy of sudoers in version control. Not the live file, a template. When someone adds a NOPASSWD rule six months from now, you'll see it in the diff.
  • Log sudo command usage. Add Defaults logfile=/var/log/sudo.log to catch anything unexpected running as root.
  • If you manage more than a handful of servers, use Ansible, Chef, or whatever config tool your team has. Hand-editing sudoers across 40 boxes always drifts.

One last thing: after you add a NOPASSWD rule, run your cron job manually with env -i to strip the environment. Cron gets a bare environment and no TTY, so this reveals problems your interactive shell hides.

Related Errors in Linux & Unix
EACCES Linux: Fix 'Permission Denied' in 5 Minutes Linux 'Permission denied' on mount: fix it fast Fix SSH Permission Denied with Public Key Authentication E: dpkg was interrupted Fix dpkg Interrupted Error: Run dpkg --configure -a

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.