{"record":{"id":"febf0c9e11a3b9c8","repo":"juicedata/juicefs","slug":"invalid-endpoint-v-error-v-febf0c","errorCode":null,"errorMessage":"invalid endpoint: %v, error: %v","messagePattern":"invalid endpoint: (.+?), error: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/tos.go","lineNumber":316,"sourceCode":"\treturn err\n}\nfunc (t *tosClient) Restore(ctx context.Context, key string, days int32) error {\n\t_, err := t.client.RestoreObject(ctx, &tos.RestoreObjectInput{\n\t\tBucket:               t.bucket,\n\t\tKey:                  key,\n\t\tDays:                 int(days),\n\t\tRestoreJobParameters: &tos.RestoreJobParameters{Tier: enum.TierStandard},\n\t})\n\treturn err\n}\n\nfunc newTOS(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: %v, error: %v\", endpoint, err)\n\t}\n\tdisableChecksum := strings.EqualFold(uri.Query().Get(\"disable-checksum\"), \"true\")\n\tif disableChecksum {\n\t\tlogger.Infof(\"default CRC checksum is disabled\")\n\t}\n\thostParts := strings.SplitN(uri.Host, \".\", 3)\n\tcredentials := tos.NewStaticCredentials(accessKey, secretKey)\n\tcredentials.WithSecurityToken(token)\n\tcli, err := tos.NewClientV2(\n\t\thostParts[1]+\".\"+hostParts[2],\n\t\ttos.WithRegion(strings.TrimPrefix(hostParts[1], \"tos-\")),\n\t\ttos.WithCredentials(credentials),\n\t\ttos.WithUserAgentProductName(UserAgent),\n\t\ttos.WithEnableVerifySSL(httpClient.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify),\n\t\ttos.WithEnableCRC(!disableChecksum))\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/tos.go#L298-L334","documentation":"url.ParseRequestURI rejected the Volcengine TOS endpoint after HTTPS scheme prefixing. Validation guard: the endpoint string is not a parseable URI, so the TOS SDK client cannot be constructed for it.","triggerScenarios":"Creating a TOS object store with an endpoint that is empty, contains illegal characters, or is otherwise unparseable as a URL even after adding the https:// scheme (e.g. \"tos://bad url\", \"not%valid\").","commonSituations":"Typo or stray whitespace in the endpoint config value; pasting a full TOS ARN instead of a host; config template variable left unexpanded; URL-encoded characters that break ParseRequestURI.","solutions":["Print and inspect the endpoint string; remove whitespace/control characters","Use a plain host like tos-cn-beijing.volces.com, or with an explicit https:// scheme","Ensure the config value is actually substituted (no leftover {{var}} or $VAR)","Percent-encode any characters that are not valid in a URL"],"exampleFix":"// before\n--storage-url \"tos://tos cn-beijing.volces.com\"\n// after\n--storage-url \"tos://tos-cn-beijing.volces.com\"","handlingStrategy":"validation","validationCode":"func validTOSEndpoint(ep string) error {\n\tif !strings.Contains(ep, \"://\") { ep = \"https://\" + ep }\n\t_, err := url.ParseRequestURI(ep)\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"_, err := object.CreateStorage(ctx, \"tos\", url, ak, sk)\nif err != nil && strings.HasPrefix(err.Error(), \"invalid endpoint\") {\n\t// fix the endpoint string and retry\n}","preventionTips":["Trim whitespace from endpoint config values","Use host[:port] or a scheme-qualified URL only","Template-expand config variables before use"],"tags":["tos","endpoint","url-parse","object-storage"],"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"}