{"record":{"id":"8b1718ec5afc30ee","repo":"docker/cli","slug":"incorrect-scheme","errorCode":null,"errorMessage":"incorrect scheme: ","messagePattern":"incorrect scheme: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/connhelper/ssh/ssh.go","lineNumber":46,"sourceCode":"// an error if the URL is using the wrong scheme, contains fragments,\n// query-parameters, or contains a password.\nfunc NewSpec(sshURL *url.URL) (*Spec, error) {\n\ts, err := newSpec(sshURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid SSH URL: %w\", err)\n\t}\n\treturn s, nil\n}\n\nfunc newSpec(u *url.URL) (*Spec, error) {\n\tif u == nil {\n\t\treturn nil, errors.New(\"URL is nil\")\n\t}\n\tif u.Scheme == \"\" {\n\t\treturn nil, errors.New(\"no scheme provided\")\n\t}\n\tif u.Scheme != \"ssh\" {\n\t\treturn nil, errors.New(\"incorrect scheme: \" + u.Scheme)\n\t}\n\n\tvar sp Spec\n\n\tif u.User != nil {\n\t\tsp.User = u.User.Username()\n\t\tif _, ok := u.User.Password(); ok {\n\t\t\treturn nil, errors.New(\"plain-text password is not supported\")\n\t\t}\n\t}\n\tsp.Host = u.Hostname()\n\tif sp.Host == \"\" {\n\t\treturn nil, errors.New(\"hostname is empty\")\n\t}\n\tsp.Port = u.Port()\n\tsp.Path = u.Path\n\tif u.RawQuery != \"\" {\n\t\treturn nil, fmt.Errorf(\"query parameters are not allowed: %q\", u.RawQuery)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/connhelper/ssh/ssh.go#L28-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"A user expects the helper to fall back to TCP but it refuses. Passing an http(s) endpoint into the SSH parser by mistake.","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."],"exampleFix":"# before\nDOCKER_HOST=tcp://remote-host\n# after (for SSH transport)\nDOCKER_HOST=ssh://user@remote-host","handlingStrategy":"type-guard","validationCode":"const allowedSchemes = map[string]bool{\"ssh\": true, \"tcp\": true, \"unix\": true, \"npipe\": true, \"fd\": true}\nif u, err := url.Parse(host); err == nil && !allowedSchemes[u.Scheme] {\n    return fmt.Errorf(\"unsupported scheme %q\", u.Scheme)\n}","typeGuard":"func isSSHURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && u.Scheme == \"ssh\"\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["ssh","connhelper","docker-host","url-parsing","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}