{"record":{"id":"525e60837a7a4a91","repo":"juicedata/juicefs","slug":"invalid-endpoint-s","errorCode":null,"errorMessage":"invalid endpoint: %s","messagePattern":"invalid endpoint: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/ks3.go","lineNumber":385,"sourceCode":"\t\"cn-guangzhou\": \"GUANGZHOU\",\n\t\"cn-qingdao\":   \"QINGDAO\",\n\t\"jr-beijing\":   \"JR_BEIJING\",\n\t\"jr-shanghai\":  \"JR_SHANGHAI\",\n\t\"\":             \"HANGZHOU\",\n\t\"cn-hk-1\":      \"HONGKONG\",\n\t\"rus\":          \"RUSSIA\",\n\t\"sgp\":          \"SINGAPORE\",\n}\n\nfunc newKS3(endpoint, accessKey, secretKey, token string) (ObjectStorage, error) {\n\tif !strings.Contains(endpoint, \"://\") {\n\t\tendpoint = fmt.Sprintf(\"https://%s\", endpoint)\n\t}\n\turi, _ := url.ParseRequestURI(endpoint)\n\tssl := strings.ToLower(uri.Scheme) == \"https\"\n\thostParts := strings.Split(uri.Host, \".\")\n\tif len(hostParts) < 2 {\n\t\treturn nil, fmt.Errorf(\"invalid endpoint: %s\", endpoint)\n\t}\n\tbucket := hostParts[0]\n\tregion := hostParts[1][3:]\n\tregion = strings.TrimLeft(region, \"-\")\n\tvar pathStyle bool = defaultPathStyle()\n\tif strings.HasSuffix(uri.Host, \"ksyun.com\") || strings.HasSuffix(uri.Host, \"ksyuncs.com\") {\n\t\tregion = strings.TrimSuffix(region, \"-internal\")\n\t\tregion = ks3Regions[region]\n\t\tpathStyle = false\n\t} else if envRegion := os.Getenv(\"AWS_REGION\"); envRegion != \"\" {\n\t\tregion = envRegion\n\t}\n\tif region == \"\" {\n\t\tregion = \"us-east-1\"\n\t}\n\n\tvar err error\n\taccessKey, err = url.PathUnescape(accessKey)","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/ks3.go#L367-L403","documentation":"newKS3 in pkg/object/ks3.go parses the endpoint host as <bucket>.<region-host>; it splits the host on '.' and requires at least two labels. When the host has fewer than two dot-separated labels (e.g. 'localhost' or a bare hostname), the constructor cannot derive a bucket and region, so it rejects the endpoint.","triggerScenarios":"Creating a KS3 object store with an endpoint whose host has no dot, e.g. 'ks3://bucket@localhost/' or a bare hostname without a domain, or an endpoint missing the bucket prefix entirely.","commonSituations":"Local testing against a KS3-compatible proxy on localhost; typo where the bucket label is dropped ('ks3.cn-north-1.ksyuncs.com' without the leading bucket); using a Unix host alias instead of an FQDN.","solutions":["Use a full virtual-host-style endpoint with the bucket prefix and a multi-label host, e.g. 'mybucket.ks3-cn-beijing.ksyuncs.com'.","If testing locally, use a hostname with at least one dot (e.g. 'ks3.local') and make it resolvable via /etc/hosts.","Verify the endpoint URL is complete and not truncated by shell quoting or config parsing."],"exampleFix":"// before\ncreateStorage(\"ks3\", \"localhost\", ak, sk)\n// after\ncreateStorage(\"ks3\", \"mybucket.ks3-cn-beijing.ksyuncs.com\", ak, sk)","handlingStrategy":"validation","validationCode":"func validKS3Endpoint(ep string) bool {\n\thost := ep\n\tif i := strings.Index(host, \"://\"); i >= 0 { host = host[i+3:] }\n\tif i := strings.IndexAny(host, \"/?\"); i >= 0 { host = host[:i] }\n\treturn len(strings.Split(host, \".\")) >= 2\n}","typeGuard":null,"tryCatchPattern":"store, err := newKS3(endpoint, ak, sk, \"\")\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid endpoint\") {\n\t\tlog.Fatalf(\"endpoint %q must be virtual-host style: bucket.region-host\", endpoint)\n\t}\n\treturn err\n}","preventionTips":["Always include the bucket as the first host label of the KS3 endpoint.","Use FQDNs, never bare hostnames or 'localhost', for object-storage endpoints.","Validate endpoint format at config-load time with a unit test."],"tags":["object-storage","url","configuration"],"backgroundTag":"invalid-url-format","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}