{"record":{"id":"38caa224beb4d8fc","repo":"kubernetes/kops","slug":"error-parsing-location-q-not-a-valid-uri","errorCode":null,"errorMessage":"error parsing location %q - not a valid URI","messagePattern":"error parsing location %q - not a valid URI","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/context.go","lineNumber":132,"sourceCode":"\tctx := context.TODO()\n\n\tvar opts vfsOptions\n\t// Exponential backoff, starting with 500 milliseconds, doubling each time, 5 steps\n\topts.backoff = wait.Backoff{\n\t\tDuration: 500 * time.Millisecond,\n\t\tFactor:   2,\n\t\tSteps:    5,\n\t}\n\n\tfor _, option := range options {\n\t\toption(&opts)\n\t}\n\n\tif strings.Contains(location, \"://\") && !strings.HasPrefix(location, \"file://\") {\n\t\t// Handle our special case schemas\n\t\tu, err := url.Parse(location)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing location %q - not a valid URI\", location)\n\t\t}\n\n\t\tswitch u.Scheme {\n\t\tcase \"metadata\":\n\t\t\tswitch u.Host {\n\t\t\tcase \"gce\":\n\t\t\t\thttpURL := \"http://169.254.169.254/computeMetadata/v1/\" + u.Path\n\t\t\t\thttpHeaders := make(map[string]string)\n\t\t\t\thttpHeaders[\"Metadata-Flavor\"] = \"Google\"\n\t\t\t\treturn c.readHTTPLocation(httpURL, httpHeaders, opts)\n\t\t\tcase \"aws\":\n\t\t\t\treturn c.readAWSMetadata(ctx, u.Path)\n\t\t\tcase \"digitalocean\":\n\t\t\t\thttpURL := \"http://169.254.169.254/metadata/v1\" + u.Path\n\t\t\t\treturn c.readHTTPLocation(httpURL, nil, opts)\n\t\t\tcase \"openstack\":\n\t\t\t\thttpURL := \"http://169.254.169.254/latest/meta-data/\" + u.Path\n\t\t\t\treturn c.readHTTPLocation(httpURL, nil, opts)","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/context.go#L114-L150","documentation":"VFSContext.ReadFile parses a location string with net/url.Parse when it contains \"://\" and is not a file:// URL. If url.Parse fails, the location is not a syntactically valid URI, so kOps cannot determine the scheme and returns this error instead of reading any file.","triggerScenarios":"Calling ReadFile (directly or via updateAddon, LoadAddons, LoadChannel, Run, transferFile, findHash) with a location containing \"://\" that url.Parse rejects - e.g. control characters, malformed percent-encoding like 'https://host/%zz', or a bad scheme such as 'ht tp://x' built by string concatenation.","commonSituations":"Typo in a --state store or addon/channel URL in cluster config; programmatic construction of URLs from unvalidated user input or environment variables; shell interpolation inserting spaces into a URI.","solutions":["Print the exact location value in the error and run url.Parse on it in a scratch program to see the specific parse error","Fix the malformed URI in the config/flag/environment value that produced it","Validate the location with url.ParseRequestURI before passing it to ReadFile","If the value is a local path that happens to contain '://', restructure it or use a file:// prefix explicitly"],"exampleFix":"// before\nkops.ReadFile(cfg.BaseURL + \"/channel\") // BaseURL = \"https://example.com \"/a b\"\n// after\nu, err := url.Parse(cfg.BaseURL + \"/channel\")\nif err != nil {\n\treturn fmt.Errorf(\"invalid channel location: %w\", err)\n}\ndata, err := kops.ReadFile(u.String())","handlingStrategy":"validation","validationCode":"func validateVFSLocation(loc string) error {\n\tif !strings.Contains(loc, \"://\") || strings.HasPrefix(loc, \"file://\") {\n\t\treturn nil\n\t}\n\tif _, err := url.Parse(loc); err != nil {\n\t\treturn fmt.Errorf(\"invalid vfs location %q: %w\", loc, err)\n\t}\n\treturn nil\n}","typeGuard":"func isParsableURI(loc string) bool {\n\tu, err := url.Parse(loc)\n\treturn err == nil && u.Scheme != \"\"\n}","tryCatchPattern":"data, err := vfs.Context.ReadFile(loc)\nif err != nil && strings.Contains(err.Error(), \"not a valid URI\") {\n\treturn fmt.Errorf(\"check the location value %q: %w\", loc, err)\n}","preventionTips":["Validate any user- or env-supplied URL with url.Parse before storing/passing it","Avoid building URLs via raw string concatenation; use url.URL and u.String()","Quote shell variables so spaces never leak into URLs"],"tags":["vfs","url-parsing","validation"],"backgroundTag":"invalid-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"}