docker/cli · error

invalid user

Error message

invalid user: %w

What it means

Raised in Spec.args (ssh.go:110-112) when the user portion of the ssh URL cannot be POSIX-shell-quoted by syntax.Quote. The user string is parsed from the URL (URL-decoded) and must be re-quoted before being passed to ssh's `-l` flag; if it contains bytes the quoting library cannot handle, this wraps the error.

Solutions

  1. Inspect the username in the DOCKER_HOST URL for hidden/control characters.
  2. Re-enter the username as plain ASCII, avoiding control characters.
  3. Percent-encode any legitimately special characters in the URL username.

Example fix

# before — hidden control char in username (e.g. NUL)
export DOCKER_HOST='ssh://user<x00>@host'
# after — clean ASCII username
export DOCKER_HOST='ssh://user@host'
Defensive patterns

Strategy: validation

Validate before calling

u, _ := url.Parse(daemonURL)
if u != nil && u.User != nil {
    if !isPrintableASCII(u.User.Username()) {
        return errors.New("ssh URL username must be printable ASCII")
    }
}

Type guard

func isPrintableASCII(s string) bool {
    for _, r := range s {
        if r < 0x20 || r > 0x7e {
            return false
        }
    }
    return true
}

Try / catch

args, err := spec.Args(remote...)
if err != nil {
    return fmt.Errorf("cannot build ssh args (bad user?): %w", err)
}

Prevention

When it happens

Trigger: Spec.args/Args/Command is called after a Spec was built from a URL whose User field contains characters that syntax.Quote rejects (e.g. a NUL byte or other control character that cannot appear in a POSIX-safe token).

Common situations: A DOCKER_HOST ssh URL with a username containing an embedded NUL or other non-printable control character, often from a misencoded environment variable or a copy-paste with hidden bytes. Extremely rare in normal use.

Related errors


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

Appendix: source

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

	if err != nil {
		return nil
	}
	if remoteCommand != "" {
		sshArgs = append(sshArgs, remoteCommand)
	}
	return sshArgs
}

func (sp *Spec) args(sshFlags ...string) ([]string, error) {
	var args []string
	if sp.Host == "" {
		return nil, errors.New("no host specified")
	}
	if sp.User != "" {
		// Quote user, as it's obtained from the URL.
		usr, err := syntax.Quote(sp.User, syntax.LangPOSIX)
		if err != nil {
			return nil, fmt.Errorf("invalid user: %w", err)
		}
		args = append(args, "-l", usr)
	}
	if sp.Port != "" {
		// Quote port, as it's obtained from the URL.
		port, err := syntax.Quote(sp.Port, syntax.LangPOSIX)
		if err != nil {
			return nil, fmt.Errorf("invalid port: %w", err)
		}
		args = append(args, "-p", port)
	}

	// We consider "sshFlags" to be "trusted", and set from code only,
	// as they are not parsed from the DOCKER_HOST URL.
	args = append(args, sshFlags...)

	host, err := syntax.Quote(sp.Host, syntax.LangPOSIX)
	if err != nil {

View on GitHub (pinned to 4f84911bfe)