{"record":{"id":"b698bd8b8747b975","repo":"juicedata/juicefs","slug":"invalid-endpoint-s-s-b698bd","errorCode":null,"errorMessage":"Invalid endpoint %s: %s","messagePattern":"Invalid endpoint (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/cos.go","lineNumber":327,"sourceCode":"\t}\n\n\tfor _, b := range s.Buckets {\n\t\t// fmt.Printf(\"%#v\\n\", b)\n\t\tif b.Name == bucketName {\n\t\t\treturn fmt.Sprintf(\"https://%s.cos.%s.myqcloud.com\", b.Name, b.Region), nil\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"bucket %q doesn't exist\", bucketName)\n}\n\nfunc newCOS(endpoint, accessKey, secretKey, token string) (ObjectStorage, error) {\n\tif !strings.Contains(endpoint, \"://\") {\n\t\tendpoint = fmt.Sprintf(\"https://%s\", endpoint)\n\t}\n\turi, err := url.ParseRequestURI(endpoint)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Invalid endpoint %s: %s\", endpoint, err)\n\t}\n\thostParts := strings.SplitN(uri.Host, \".\", 2)\n\n\tif accessKey == \"\" {\n\t\taccessKey = os.Getenv(\"COS_SECRETID\")\n\t\tsecretKey = os.Getenv(\"COS_SECRETKEY\")\n\t}\n\n\tif len(hostParts) == 1 {\n\t\tif endpoint, err = autoCOSEndpoint(hostParts[0], accessKey, secretKey, token); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Unable to get endpoint of bucket %s: %s\", hostParts[0], err)\n\t\t}\n\t\tif uri, err = url.ParseRequestURI(endpoint); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Invalid endpoint %s: %s\", endpoint, err)\n\t\t}\n\t\tlogger.Debugf(\"Use endpoint %q\", endpoint)\n\t}\n","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/cos.go#L309-L345","documentation":"newCOS parses the endpoint with url.ParseRequestURI and wraps any parse failure in this error. The endpoint must be a syntactically valid absolute URL identifying the COS bucket (or be auto-completed with https:// when it lacks a scheme).","triggerScenarios":"Passing an endpoint that fails url.ParseRequestURI even after the https:// prefix is added — e.g. \"my bucket\", \"https://[bad\", control characters, or an empty string.","commonSituations":"Spaces or invalid characters in the endpoint config; unescaped characters; truncated endpoint values from env files; accidentally passing the whole storage URI instead of the endpoint.","solutions":["Fix the endpoint string to a valid absolute URL like https://<bucket>.cos.<region>.myqcloud.com.","URL-encode or remove spaces/invalid characters in the configured endpoint.","Print/log the endpoint value to spot hidden whitespace or truncation before calling newCOS."],"exampleFix":"// before\nnewCOS(\"https://my bucket.cos.ap-guangzhou.myqcloud.com\", ...)\n// after\nnewCOS(\"https://mybucket.cos.ap-guangzhou.myqcloud.com\", ...)","handlingStrategy":"validation","validationCode":"ep := endpoint\nif !strings.Contains(ep, \"://\") {\n    ep = \"https://\" + ep\n}\nif _, err := url.ParseRequestURI(ep); err != nil {\n    return fmt.Errorf(\"endpoint %q is not a valid URL: %v\", endpoint, err)\n}","typeGuard":"func isValidEndpoint(endpoint string) bool {\n    if !strings.Contains(endpoint, \"://\") {\n        endpoint = \"https://\" + endpoint\n    }\n    _, err := url.ParseRequestURI(endpoint)\n    return err == nil\n}","tryCatchPattern":"obj, err := object.CreateStorage(\"cos\", endpoint, ak, sk, \"\")\nif err != nil && strings.Contains(err.Error(), \"Invalid endpoint\") {\n    return fmt.Errorf(\"check COS endpoint config: %w\", err)\n}","preventionTips":["Trim whitespace from endpoint config values","Reject endpoints with spaces or unencoded special chars early","Keep endpoints in dedicated config fields, not concatenated URIs"],"tags":["cos","tencent","url-validation","config"],"backgroundTag":"invalid-url","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"}