gravitational/teleport · error
failed to retrieve stdout mode: %w
Error message
failed to retrieve stdout mode: %w
What it means
initTerminal calls winterm.GetConsoleMode on the Windows stdout handle (syscall.Stdout) before enabling VT processing. If the OS refuses to read the console mode, the call is aborted and this wrapped error is returned through Terminal.InitRaw. It means the process's standard output is not an interactive Windows console buffer (or the console API failed), so raw/VT terminal mode cannot be established.
Source
Thrown at lib/client/terminal/terminal_windows.go:49
"github.com/Azure/go-ansiterm/winterm"
"github.com/gravitational/trace"
"github.com/moby/term"
"github.com/gravitational/teleport/lib/client/tncon"
"github.com/gravitational/teleport/lib/utils"
)
// initTerminal configures the terminal for raw, VT compatible output and
// optionally input. The returned function should be called before program
// exit to ensure the terminal is reset, otherwise it will be left in a broken
// state.
func initTerminal(input bool) (func(), error) {
stdoutFd := int(syscall.Stdout)
stdinFd := int(syscall.Stdin)
oldOutMode, err := winterm.GetConsoleMode(uintptr(stdoutFd))
if err != nil {
return func() {}, fmt.Errorf("failed to retrieve stdout mode: %w", err)
}
oldInMode, err := winterm.GetConsoleMode(uintptr(stdinFd))
if err != nil {
return func() {}, fmt.Errorf("failed to retrieve stdout mode: %w", err)
}
newOutMode := oldOutMode | winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING | winterm.DISABLE_NEWLINE_AUTO_RETURN
err = winterm.SetConsoleMode(uintptr(stdoutFd), newOutMode)
if err != nil {
return func() {}, fmt.Errorf("failed to set stdout mode: %w", err)
}
if input {
newInMode := oldInMode
newInMode &^= winterm.ENABLE_ECHO_INPUT
newInMode &^= winterm.ENABLE_LINE_INPUTView on GitHub (pinned to 1283425b60)
Solutions
- Run the client in a real interactive Windows console (conhost or Windows Terminal) with stdout attached to the console, not redirected.
- Before calling InitRaw, check term.IsTerminal(os.Stdout.Fd()) (moby/term) and skip raw mode when stdout is not a console.
- If running programmatically or in CI, use the library in non-interactive mode instead of requesting raw terminal capture.
- Ensure the process has an attached console (e.g. launch via a terminal rather than a detached/service context); use AttachConsole/AllocConsole if embedding.
Example fix
// before
cleanup, err := term.InitRaw(true)
if err != nil {
return err
}
// after
if !term.IsTerminal(os.Stdout.Fd()) {
return errors.New("stdout is not an interactive console; cannot enable raw mode")
}
cleanup, err := term.InitRaw(true)
if err != nil {
return trace.Wrap(err)
} Defensive patterns
Strategy: validation
Validate before calling
import "github.com/moby/term"
if !term.IsTerminal(os.Stdout.Fd()) {
return errors.New("stdout is not an interactive Windows console; raw terminal mode unavailable")
} Type guard
func isConsole(f *os.File) bool {
return term.IsTerminal(f.Fd())
} Try / catch
cleanup, err := t.InitRaw(input)
if err != nil {
var consoleErr *fmt.Errorf
if errors.As(err, &consoleErr) && strings.Contains(err.Error(), "failed to retrieve stdout mode") {
log.Warn("no interactive console on stdout; disabling raw mode")
cleanup = func() {}
} else {
return trace.Wrap(err)
}
} Prevention
- Always run interactive Teleport clients from a real terminal (conhost/Windows Terminal), not with redirected stdout.
- Guard InitRaw behind term.IsTerminal(os.Stdout.Fd()) checks.
- In CI or scripted contexts, use non-interactive modes instead of raw terminal capture.
When it happens
Trigger: Calling Terminal.InitRaw on Windows when GetConsoleMode(stdout) fails: stdout is redirected to a file or pipe, the process runs without an attached console (e.g. a service, scheduled task, or CI runner), or the console host returns an error for the pseudo handle.
Common situations: Running `tsh ssh` or another Teleport client interactively with `> out.log` redirection; invoking the client from a non-console parent (IDE run tool, ssh without a pty, Windows service); using a legacy terminal host that does not expose console mode APIs for the stdout handle.
Related errors
- failed to set stdout mode: %w
- failed to set stdin mode: %w
- a tncon session is already active
- unexpected nil response from GetAssertion
- unexpected nil response from MakeCredential
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/be37f4b88b31ebb5.
Report an issue: GitHub.