docker/cli · error

invalid argument

Error message

invalid argument: %w

What it means

Returned by ssh.Spec.Command() when a remote-command argument cannot be safely quoted for execution in a POSIX shell on the remote host. The wrapped error is a *syntax.QuoteError (mvdan.cc/shell quoting). The POSIX variant has no escape sequences for non-printable runes, and no variant can represent a NUL byte, so such input is rejected to avoid emitting an invalid or unsafe shell command. Note: Spec.Args() swallows this error (returns nil args); only Command() surfaces it.

Solutions

  1. Sanitize each argument: reject or strip NUL bytes and non-printable control characters before calling Command.
  2. Transmit binary data via stdin or a remote file path instead of as a positional command argument.
  3. Validate that each arg is valid UTF-8 containing only printable runes (unicode.IsPrint) before use.

Example fix

// before
cmd, err := spec.Command(flags, userInput)
// userInput may contain control chars / NUL -> "invalid argument"

// after
for _, a := range userInput {
    if !isPrintableSafe(a) {
        return fmt.Errorf("unsafe argument %q", a)
    }
}
cmd, err := spec.Command(flags, userInput)
Defensive patterns

Strategy: validation

Validate before calling

// isSafeSSHArg reports whether s can be POSIX-quoted by the ssh helper.
func isSafeSSHArg(s string) bool {
    for _, r := range s {
        if r == 0 || r == utf8.RuneError || !unicode.IsPrint(r) {
            return false
        }
    }
    return utf8.ValidString(s)
}

for _, a := range args {
    if !isSafeSSHArg(a) {
        return fmt.Errorf("argument contains non-quotable characters")
    }
}
cmd, err := spec.Command(flags, args...)

Try / catch

var quoteErr *syntax.QuoteError
if errors.As(err, &quoteErr) {
    // an argument could not be shell-quoted; sanitize input and retry, or reject
}

Prevention

When it happens

Trigger: Calling spec.Command(sshFlags, remoteCommandAndArgs...) where one of remoteCommandAndArgs contains a NUL byte (\x00), a non-printable/control rune (e.g. bell \x07, ESC \x1b), invalid UTF-8 (utf8.RuneError), or a codepoint > utf8.MaxRune. The package always uses LangPOSIX, under which any non-printable rune is fatal.

Common situations: Passing binary/blob payloads as a literal command argument; embedding ANSI/terminal escape sequences; reading args from env vars, files, or sockets that may carry control characters; garbled/mojibake input piped into the helper.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/4fcce9a08ab4cb83. Report an issue: GitHub.

Appendix: source

Thrown at cli/connhelper/ssh/ssh.go:172

	remoteCommand, err := quoteCommand(remoteCommandAndArgs...)
	if err != nil {
		return nil, err
	}
	if remoteCommand != "" {
		sshArgs = append(sshArgs, remoteCommand)
	}
	return sshArgs, nil
}

// quoteCommand returns the remote command to run using the ssh connection
// as a single string, quoting values where needed because ssh executes
// these in a POSIX shell.
func quoteCommand(commandAndArgs ...string) (string, error) {
	var quotedCmd string
	for i, arg := range commandAndArgs {
		a, err := syntax.Quote(arg, syntax.LangPOSIX)
		if err != nil {
			return "", fmt.Errorf("invalid argument: %w", err)
		}
		if i == 0 {
			quotedCmd = a
			continue
		}
		quotedCmd += " " + a
	}
	// each part is quoted appropriately, so now we'll have a full
	// shell command to pass off to "ssh"
	return quotedCmd, nil
}

View on GitHub (pinned to 4f84911bfe)