{"record":{"id":"293e888eddfb6367","repo":"k3s-io/k3s","slug":"proxy-url-must-include-scheme-and-host","errorCode":null,"errorMessage":"proxy URL must include scheme and host","messagePattern":"proxy URL must include scheme and host","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/etcd/s3/s3.go","lineNumber":204,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttr.TLSClientConfig = tlsConfig\n\t}\n\n\t// Set a fixed proxy URL, if requested by the user. This replaces the default,\n\t// which calls ProxyFromEnvironment to read proxy settings from the environment.\n\tif etcdS3.Proxy != \"\" {\n\t\tvar u *url.URL\n\t\tvar err error\n\t\t// proxy address of literal \"none\" disables all use of a proxy by S3\n\t\tif etcdS3.Proxy != \"none\" {\n\t\t\tu, err = url.Parse(etcdS3.Proxy)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.WithMessage(err, \"failed to parse etcd-s3-proxy value as URL\")\n\t\t\t}\n\t\t\tif u.Scheme == \"\" || u.Host == \"\" {\n\t\t\t\treturn nil, errors.New(\"proxy URL must include scheme and host\")\n\t\t\t}\n\t\t}\n\t\ttr.Proxy = http.ProxyURL(u)\n\t}\n\n\tcreds := credentials.NewChainCredentials([]credentials.Provider{\n\t\t&credentials.Static{\n\t\t\tValue: credentials.Value{\n\t\t\t\tAccessKeyID:     etcdS3.AccessKey,\n\t\t\t\tSecretAccessKey: etcdS3.SecretKey,\n\t\t\t\tSessionToken:    etcdS3.SessionToken,\n\t\t\t\tSignerType:      credentials.SignatureV4,\n\t\t\t},\n\t\t},\n\t\t&credentials.FileAWSCredentials{},\n\t\t&credentials.IAM{},\n\t})\n","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/etcd/s3/s3.go#L186-L222","documentation":"When --etcd-s3-proxy is set (and is not the literal 'none'), the value is parsed with url.Parse and must yield both a scheme and a host before it is installed as the transport proxy. url.Parse rarely errors on sloppy input, so this explicit check is what rejects ambiguous proxy strings.","triggerScenarios":"Setting --etcd-s3-proxy=10.10.10.1:8080 (missing scheme) or --etcd-s3-proxy=http:// (missing host); anything url.Parse accepts but that lacks scheme/host fails here.","commonSituations":"Reusing a proxy value from environment-style configs (which omit the scheme) in a flag that requires it; typos like 'http:/proxy:3128'; expecting the literal 'none' semantics with values like 'off' or 'disabled' (only 'none' is special).","solutions":["Include scheme and host: --etcd-s3-proxy=http://10.10.10.1:8080.","To explicitly disable proxying use the literal --etcd-s3-proxy=none; to fall back to environment proxies, unset the flag.","Validate the value with url.ParseRequestURI in CI/scripts before passing it to the server."],"exampleFix":"# before\n--etcd-s3-proxy=10.10.10.1:8080\n# after\n--etcd-s3-proxy=http://10.10.10.1:8080","handlingStrategy":"validation","validationCode":"if etcdS3.Proxy != \"\" && etcdS3.Proxy != \"none\" {\n    u, err := url.Parse(etcdS3.Proxy)\n    if err != nil || u.Scheme == \"\" || u.Host == \"\" {\n        return fmt.Errorf(\"proxy %q must look like http://host:port\", etcdS3.Proxy)\n    }\n}","typeGuard":"func hasSchemeAndHost(s string) bool {\n\tu, err := url.Parse(s)\n\treturn err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":null,"preventionTips":["Standardize proxy values in config management as scheme://host:port.","Use the literal 'none' to disable; never invent other keywords."],"tags":["s3","proxy","configuration","url-parsing"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}