docker/cli · error
incorrect scheme:
Error message
incorrect scheme:
What it means
Returned by newSpec when the URL has a scheme but it is not 'ssh' (the message appends the offending scheme, e.g. 'incorrect scheme: tcp'). The SSH connection helper is invoked for non-socket, non-tcp hosts but only knows how to build ssh command lines, so any other scheme is rejected.
Source
Thrown at cli/connhelper/ssh/ssh.go:46
// an error if the URL is using the wrong scheme, contains fragments,
// query-parameters, or contains a password.
func NewSpec(sshURL *url.URL) (*Spec, error) {
s, err := newSpec(sshURL)
if err != nil {
return nil, fmt.Errorf("invalid SSH URL: %w", err)
}
return s, nil
}
func newSpec(u *url.URL) (*Spec, error) {
if u == nil {
return nil, errors.New("URL is nil")
}
if u.Scheme == "" {
return nil, errors.New("no scheme provided")
}
if u.Scheme != "ssh" {
return nil, errors.New("incorrect scheme: " + u.Scheme)
}
var sp Spec
if u.User != nil {
sp.User = u.User.Username()
if _, ok := u.User.Password(); ok {
return nil, errors.New("plain-text password is not supported")
}
}
sp.Host = u.Hostname()
if sp.Host == "" {
return nil, errors.New("hostname is empty")
}
sp.Port = u.Port()
sp.Path = u.Path
if u.RawQuery != "" {
return nil, fmt.Errorf("query parameters are not allowed: %q", u.RawQuery)View on GitHub (pinned to 4f84911bfe)
Solutions
- Use the 'ssh://' scheme for remote Docker access over SSH.
- For TCP, set DOCKER_HOST=tcp://host:2375 (and configure TLS separately).
- Verify the URL scheme matches the intended transport before passing it to ssh.ParseURL.
Example fix
# before DOCKER_HOST=tcp://remote-host # after (for SSH transport) DOCKER_HOST=ssh://user@remote-host
Defensive patterns
Strategy: type-guard
Validate before calling
const allowedSchemes = map[string]bool{"ssh": true, "tcp": true, "unix": true, "npipe": true, "fd": true}
if u, err := url.Parse(host); err == nil && !allowedSchemes[u.Scheme] {
return fmt.Errorf("unsupported scheme %q", u.Scheme)
} Type guard
func isSSHURL(s string) bool {
u, err := url.Parse(s)
return err == nil && u.Scheme == "ssh"
} Prevention
- Only route ssh:// URLs into the SSH helper.
- Validate the scheme matches the intended transport upstream.
- Keep TCP endpoints out of SSH parsing code paths.
When it happens
Trigger: The SSH helper receives a URL like 'tcp://host', 'http://host', or 'fd://host'. This happens when DOCKER_HOST is set to a scheme the helper does not handle but the dispatcher routed it here, or when explicitly calling ssh.NewSpec with a non-ssh URL.
Common situations: A user expects the helper to fall back to TCP but it refuses. Passing an http(s) endpoint into the SSH parser by mistake.
Related errors
- hostname is empty
- no scheme provided
- plain-text password is not supported
- no remote command specified
- ssh host connection is not valid: %w
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/8b1718ec5afc30ee.
Report an issue: GitHub.