{"record":{"id":"ced508094d7b4d0f","repo":"kubernetes/kops","slug":"invalid-google-cloud-storage-path-q","errorCode":null,"errorMessage":"invalid google cloud storage path: %q","messagePattern":"invalid google cloud storage path: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/context.go","lineNumber":497,"sourceCode":"\tif c.memfsContext == nil {\n\t\t// We only initialize this in unit tests etc\n\t\treturn nil, fmt.Errorf(\"memfs context not initialized\")\n\t}\n\tfspath := NewMemFSPath(c.memfsContext, location)\n\treturn fspath, nil\n}\n\nfunc (c *VFSContext) ResetMemfsContext(clusterReadable bool) {\n\tc.memfsContext = NewMemFSContext()\n\tif clusterReadable {\n\t\tc.memfsContext.MarkClusterReadable()\n\t}\n}\n\nfunc (c *VFSContext) buildGCSPath(p string) (*GSPath, error) {\n\tu, err := url.Parse(p)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid google cloud storage path: %q\", p)\n\t}\n\n\tif u.Scheme != \"gs\" {\n\t\treturn nil, fmt.Errorf(\"invalid google cloud storage path: %q\", p)\n\t}\n\n\tbucket := strings.TrimSuffix(u.Host, \"/\")\n\tif bucket == \"\" {\n\t\treturn nil, fmt.Errorf(\"invalid google cloud storage path: %q\", p)\n\t}\n\n\tgcsPath := NewGSPath(c, bucket, u.Path)\n\treturn gcsPath, nil\n}\n\n// getGCSClient returns the google cloud storage client, caching it for future calls\nfunc (c *VFSContext) getGCSClient(ctx context.Context) (*storage.Client, error) {\n\tc.mutex.Lock()","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/context.go#L479-L515","documentation":"VFSContext.buildGCSPath wraps a raw string into a GSPath VFS object. It rejects any string that url.Parse fails on, returning \"invalid google cloud storage path\". This is a client-side validation error: the path never leaves the process.","triggerScenarios":"Calling VFSContext.BuildVfsPath with a gs:// path that is so malformed url.Parse returns an error (e.g. invalid percent-encoding like \"gs://bucket/%zz\", control characters in the URL).","commonSituations":"Cluster state-store flags built by string concatenation from untrusted config values; secrets or passwords interpolated into the state store URL that break URL escaping (a literal % followed by non-hex characters); copy-pasted URLs containing stray characters.","solutions":["Percent-encode or remove special characters (%, spaces, control chars) in the path before passing it to BuildVfsPath","Print the exact path %q at the call site and run it through url.Parse in isolation to see the underlying parse error","Ensure the state store URL is configured as a proper gs://<bucket>/<prefix> string, not assembled from raw user input","Trim whitespace/newlines from configuration values before building the path"],"exampleFix":"// before\nvfsPath, err := context.BuildVfsPath(\"gs://bucket/state/\" + rawPrefix) // rawPrefix = \"my%2zzstate\"\n// after\nprefix := url.PathEscape(strings.TrimSpace(rawPrefix))\nvfsPath, err := context.BuildVfsPath(\"gs://bucket/state/\" + prefix)","handlingStrategy":"validation","validationCode":"if _, err := url.Parse(stateStore); err != nil { return fmt.Errorf(\"state store %q is not a valid URL: %v\", stateStore, err) }","typeGuard":"func isParsableURL(p string) bool { _, err := url.Parse(p); return err == nil }","tryCatchPattern":"if _, err := context.BuildVfsPath(p); err != nil { if strings.Contains(err.Error(), \"invalid google cloud storage path\") { /* reject config, show user the offending path */ } return err }","preventionTips":["Percent-encode user-supplied path segments before composing gs:// URLs","Trim whitespace and control characters from config values","Fail fast in config loading by validating the state-store URL at startup"],"tags":["gcs","url-parsing","vfs","validation"],"backgroundTag":"invalid-storage-url","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}