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
- Sanitize each argument: reject or strip NUL bytes and non-printable control characters before calling Command.
- Transmit binary data via stdin or a remote file path instead of as a positional command argument.
- 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, "eErr) {
// an argument could not be shell-quoted; sanitize input and retry, or reject
} Prevention
- Never pass binary data as a positional ssh command argument; stream it via stdin.
- Validate user-derived args with unicode.IsPrint and reject NUL/invalid UTF-8 before calling Command.
- Remember Spec.Args() silently drops the command on a quoting failure — prefer Command() if you need the error.
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
- incorrect scheme:
- hostname is empty
- no remote command specified
- query parameters are not allowed
- fragments are not allowed
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)