The "stdin is not a tty" error occurs when SSH tries to run a command without allocating a proper terminal (TTY). This typically happens when piping input or running scripts remotely. Use the -t flag to force terminal allocation.
This error means SSH has detected that standard input (stdin) is not connected to a terminal device on the remote machine. It often appears as a warning when running commands through SSH with piped input or when executing scripts remotely. The issue occurs because SSH doesn't automatically allocate a pseudo-terminal when stdin is redirected (e.g., from a pipe, file, or here-document). While the command may still execute, the warning indicates that the remote shell or program expected to be in an interactive terminal session.
The simplest fix is to use the -t flag with SSH, which forces pseudo-terminal allocation even when stdin isn't a terminal:
ssh -t user@host 'your-command'For commands that need extra terminal allocation, use -tt (double flag):
ssh -tt user@host 'interactive-command'When executing a local script on a remote server, use -t with an explicit shell command:
ssh -t user@host 'bash -s' < /path/to/local_script.shAlternatively, specify the command explicitly instead of relying on default behavior:
ssh user@host < script.sh
# becomes
ssh -t user@host /bin/bash < script.shIf you have commands in .bashrc or .profile that require a terminal (like mesg y), wrap them in a TTY check:
# Original (causes error in non-interactive SSH)
mesg y
# Fixed (only runs if stdin is a TTY)
if [ -t 0 ]; then
mesg y
fiThis allows your startup scripts to run in both interactive and non-interactive SSH sessions.
When piping data to a remote command, be explicit about what you're doing:
# This triggers the warning (implicit command, redirected stdin)
echo 'data' | ssh user@host
# Better: specify a command to handle the input
echo 'data' | ssh user@host 'cat > /tmp/file.txt'
# Or use -t if you need terminal features
echo 'password' | ssh -t user@host 'sudo -S some-command'If you encounter this with Git over SSH (in CI/CD or automation), ensure your SSH agent is properly configured:
# In GitHub Actions or similar CI systems:
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa
# Or use the -t flag for git operations if needed:
ssh -t [email protected] 'git-upload-pack /repo.git'Most modern Git setups handle this automatically, but explicit SSH configuration can help.
Understanding TTY Allocation: A TTY (teletypewriter) is a terminal interface that allows interactive communication. SSH allocates a pseudo-TTY (pty) by default only for interactive sessions. When stdin is redirected (piped, from a file, etc.), SSH knows the session isn't interactive and skips TTY allocation.
The -t vs -T flags: Use -t to force allocation, -tt for stubborn cases, and -T to explicitly disable allocation. The -T flag is useful for non-interactive operations where you want to suppress any terminal-related output.
Distro differences: This error is particularly common in cPanel-managed systems where cPanel modifies shell startup files. Some distributions (RedHat, CentOS) are more prone to startup script issues than others.
Rootless and container contexts: In Docker containers or rootless environments, TTY allocation behaves differently. Container orchestration tools often need explicit TTY allocation flags.
Performance note: Forcing TTY allocation with -t has minimal performance impact for modern SSH implementations, so it's safe to use by default when needed.
Load key "/home/user/.ssh/id_rsa": invalid format
How to fix 'Load key invalid format' in SSH
Bad owner or permissions on /home/user/.ssh/config
How to fix "Bad owner or permissions on .ssh/config" in SSH
Error connecting to agent: Connection refused
How to fix "Error connecting to agent: Connection refused" in SSH
Connection closed by UNKNOWN port 65535
How to fix 'Connection closed by UNKNOWN port 65535' in SSH
Offending ECDSA key in /home/user/.ssh/known_hosts:line
How to fix "Offending ECDSA key in known_hosts" in SSH