{"record":{"id":"2b71b2cce210d339","repo":"kubernetes/kops","slug":"invalid-linode-object-storage-path-q","errorCode":null,"errorMessage":"invalid Linode object storage path: %q","messagePattern":"invalid Linode object storage path: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/context.go","lineNumber":407,"sourceCode":"\t}\n\n\ts3path := newS3Path(c.s3Context, u.Scheme, bucket, u.Path, false, func(o *s3.Options) {\n\t\to.BaseEndpoint = aws.String(endpoint)\n\t\to.UsePathStyle = true\n\t\to.DisableLogOutputChecksumValidationSkipped = true\n\t})\n\treturn s3path, nil\n}\n\nfunc (c *VFSContext) buildLinodePath(p string) (*S3Path, error) {\n\tendpoint := os.Getenv(\"S3_ENDPOINT\")\n\tif endpoint == \"\" {\n\t\treturn nil, fmt.Errorf(\"required S3_ENDPOINT env var for path: %q\", p)\n\t}\n\n\tu, err := url.Parse(p)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid Linode object storage path: %q\", p)\n\t}\n\tif u.Scheme != \"linode\" {\n\t\treturn nil, fmt.Errorf(\"invalid Linode object storage path: %q\", p)\n\t}\n\n\tbucket := strings.TrimSuffix(u.Host, \"/\")\n\tif bucket == \"\" {\n\t\treturn nil, fmt.Errorf(\"invalid Linode object storage path: %q\", p)\n\t}\n\n\ts3path := newS3Path(c.s3Context, u.Scheme, bucket, u.Path, false, func(o *s3.Options) {\n\t\to.BaseEndpoint = aws.String(endpoint)\n\t\to.UsePathStyle = true\n\t\to.DisableLogOutputChecksumValidationSkipped = true\n\t\t// Akamai (Linode) requires checksum-when-required behavior\n\t\to.RequestChecksumCalculation = aws.RequestChecksumCalculationWhenRequired\n\t\to.ResponseChecksumValidation = aws.ResponseChecksumValidationWhenRequired\n\t})","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/context.go#L389-L425","documentation":"buildLinodePath failed to parse the given path as a URL. Linode Object Storage locations must be parseable linode://bucket/key URLs; when url.Parse errors, the path is rejected with this message.","triggerScenarios":"Calling BuildVfsPath with a linode:// string that url.Parse rejects — invalid percent-escapes (linode://bucket/%zz), control characters, or unescaped non-ASCII bytes in bucket/key.","commonSituations":"Store path assembled by templating that injects malformed characters; copy-paste artifacts in KOPS_STATE_STORE.","solutions":["Inspect the quoted path in the error and remove or percent-encode invalid characters.","Use url.PathEscape for dynamic bucket/key segments when composing the path.","Set KOPS_STATE_STORE to a clean literal like linode://my-bucket/clusters."],"exampleFix":"// before\nstatePath := fmt.Sprintf(\"linode://%s/state\", taintedName)\n// after\nstatePath := \"linode://\" + url.PathEscape(name) + \"/state\"","handlingStrategy":"validation","validationCode":"func validLinodeStorePath(p string) bool {\n\tu, err := url.Parse(p)\n\treturn err == nil && u.Scheme == \"linode\" && strings.TrimSuffix(u.Host, \"/\") != \"\"\n}\nif !validLinodeStorePath(os.Getenv(\"KOPS_STATE_STORE\")) {\n\treturn fmt.Errorf(\"KOPS_STATE_STORE must be a valid linode://bucket/path URL, got %q\", os.Getenv(\"KOPS_STATE_STORE\"))\n}","typeGuard":"func isParsableURL(p string) bool {\n\t_, err := url.Parse(p)\n\treturn err == nil\n}","tryCatchPattern":"p, err := vfs.Context.BuildVfsPath(raw)\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid Linode object storage path\") {\n\t\treturn fmt.Errorf(\"malformed Linode path %q: %w\", raw, err)\n\t}\n\treturn err\n}","preventionTips":["Set KOPS_STATE_STORE as a literal linode://bucket/path value.","Percent-encode dynamic segments with url.PathEscape.","Avoid interpolating raw/untrusted strings into the store path.","Echo the path with %q to spot hidden control characters."],"tags":["linode","object-storage","url-parsing","vfs"],"backgroundTag":"invalid-url-format","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}