docker/cli ยท error
error: cannot perform an interactive login from a non-TTY de
Error message
error: cannot perform an interactive login from a non-TTY device
What it means
Raised by loginUser (cli/command/registry/login.go:238) when the login needs to prompt interactively (username or password missing) but stdin is not a terminal (dockerCLI.In().IsTerminal() is false). Prompting for hidden-input credentials requires a real character device; a pipe or redirected stdin cannot support the no-echo password prompt, so the CLI fails up front. The source comments note this hits `cat | docker login` on Linux and mintty on Windows, where stdin is a pipe rather than a console.
Source
Thrown at cli/command/registry/login.go:238
}
if err := storeCredentials(dockerCLI.ConfigFile(), authConfig); err != nil {
return "", err
}
return resp.Auth.Status, err
}
func loginUser(ctx context.Context, dockerCLI command.Cli, opts loginOptions, defaultUsername, serverAddress string) (msg string, _ error) {
// Some links documenting this:
// - https://code.google.com/archive/p/mintty/issues/56
// - https://github.com/docker/docker/issues/15272
// - https://mintty.github.io/ (compatibility)
// Linux will hit this if you attempt `cat | docker login`, and Windows
// will hit this if you attempt docker login from mintty where stdin
// is a pipe, not a character based console.
if (opts.user == "" || opts.password == "") && !dockerCLI.In().IsTerminal() {
return "", errors.New("error: cannot perform an interactive login from a non-TTY device")
}
// If we're logging into the index server and the user didn't provide a username or password, use the device flow
if serverAddress == registry.IndexServer && opts.user == "" && opts.password == "" {
var err error
msg, err = loginWithDeviceCodeFlow(ctx, dockerCLI)
// if the error represents a failure to initiate the device-code flow,
// then we fallback to regular cli credentials login
if !errors.Is(err, manager.ErrDeviceLoginStartFail) {
return msg, err
}
_, _ = fmt.Fprint(dockerCLI.Err(), "Failed to start web-based login - falling back to command line login...\n\n")
}
return loginWithUsernameAndPassword(ctx, dockerCLI, opts, defaultUsername, serverAddress)
}
func loginWithUsernameAndPassword(ctx context.Context, dockerCLI command.Cli, opts loginOptions, defaultUsername, serverAddress string) (msg string, _ error) {View on GitHub (pinned to e9452d6e78)
Solutions
- Supply full credentials non-interactively: printf '%s' "$TOKEN" | docker login -u "$USER" --password-stdin <registry>
- On mintty/Git Bash, run `winpty docker login` or use a console with real TTY semantics (Windows Terminal, PowerShell, CMD)
- When running through ssh or docker exec, allocate a TTY (ssh -t, docker exec -it) if interactive login is genuinely wanted
Example fix
# before (CI, no TTY) docker login registry.example.com # after printf '%s' "$REGISTRY_TOKEN" | docker login -u "$REGISTRY_USER" --password-stdin registry.example.com
When it happens
Trigger: Running docker login with incomplete credentials (missing -u or password) in any non-TTY context: piped stdin (cat creds | docker login without --password-stdin), CI jobs, cron, docker exec without -t, ssh without -t, Git Bash/mintty/MSYS on Windows where stdin is emulated as a pipe.
Common situations: CI pipelines calling bare `docker login` expecting prompts; Windows users on mintty/Git Bash hitting this even in an apparently interactive shell (fix: prefix with winpty or use Windows Terminal); scripts that pipe the password on stdin but forget --password-stdin, so the CLI still thinks it must prompt.
Related errors
- conflicting options: cannot specify both --password and --pa
- error: username is required
- error: password is required
- the --password-stdin option requires --username to be set
- username is empty
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/e1467774b72a1ab7.json.
Report an issue: GitHub.