docker/cli · error
no scheme provided
Error message
no scheme provided
What it means
Returned by the SSH connection helper's newSpec when the parsed URL has an empty Scheme. The helper only understands ssh:// URLs, so a URL with no scheme (e.g. a bare 'host:port' or 'user@host') is treated as invalid because its structure is ambiguous.
Solutions
- Prefix the URL with the ssh scheme: 'ssh://user@host'.
- If you meant a plain TCP connection, use 'tcp://host:2375' so it does not enter the SSH helper.
- For a local socket, use 'unix:///var/run/docker.sock'.
Example fix
# before DOCKER_HOST=user@remote-host # after DOCKER_HOST=ssh://user@remote-host
Defensive patterns
Strategy: validation
Validate before calling
// Ensure a scheme is present before passing to ssh.ParseURL.
func ensureScheme(host string) string {
if !strings.Contains(host, "://") {
return "ssh://" + host
}
return host
} Type guard
func hasScheme(u string) bool {
return strings.Contains(u, "://")
} Prevention
- Always include the scheme in DOCKER_HOST.
- Use 'tcp://' for TCP, 'ssh://' for SSH, 'unix://' for sockets.
- Document the expected DOCKER_HOST format in your runbooks.
When it happens
Trigger: Setting DOCKER_HOST to a value without a scheme, or calling ssh.ParseURL/NewSpec with a string like '1.2.3.4:2375' or 'user@host'. The url package leaves Scheme empty for such inputs.
Common situations: A user sets DOCKER_HOST=host:port intending TCP but the value routes into the SSH helper. A misconfigured remote Docker host string missing the 'ssh://' prefix.
Related errors
- incorrect scheme:
- hostname is empty
- plain-text password is not supported
- ssh host connection is not valid
- no remote command specified
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/645e7314fa3d0015.
Report an issue: GitHub.
Appendix: source
Thrown at cli/connhelper/ssh/ssh.go:43
}
// NewSpec creates a [Spec] from the given ssh URL's properties. It returns
// 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()View on GitHub (pinned to 4f84911bfe)