{"record":{"id":"3f587988fee2e810","repo":"kubernetes/kops","slug":"parsing-azure-blob-location-w","errorCode":null,"errorMessage":"parsing Azure Blob location: %w","messagePattern":"parsing Azure Blob location: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/resources/nodeup.go","lineNumber":298,"sourceCode":"\treturn strings.Join(locations, \",\"), nil\n}\n\nfunc escapeS3Location(location string) (string, error) {\n\tu, err := url.Parse(location)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"parsing S3 location: %w\", err)\n\t}\n\tif u.Scheme != \"s3\" || u.Host == \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid S3 location\")\n\t}\n\n\treturn \"s3://\" + u.Host + httpbinding.EscapePath(u.Path, false), nil\n}\n\nfunc escapeBlobLocation(location string) (string, error) {\n\tu, err := url.Parse(location)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"parsing Azure Blob location: %w\", err)\n\t}\n\tcontainer, key, _ := strings.Cut(strings.TrimPrefix(u.Path, \"/\"), \"/\")\n\t// Reject ports, IPv6 hosts, userinfo, queries, and fragments, which the account-based\n\t// blob.core.windows.net URL cannot represent, so they fail here instead of in the boot retry loop.\n\tif u.Scheme != \"azureblob\" || u.Host == \"\" || u.Hostname() != u.Host || u.User != nil || u.RawQuery != \"\" || u.Fragment != \"\" || container == \"\" || key == \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid Azure Blob location; expected azureblob://<account>/<container>/<key>\")\n\t}\n\n\treturn \"azureblob://\" + u.Host + httpbinding.EscapePath(u.Path, false), nil\n}\n\nfunc (b *NodeUpScript) Build() (fi.Resource, error) {\n\tif b.ProxyEnv == nil {\n\t\tb.ProxyEnv = funcEmptyString\n\t}\n\tif b.EnvironmentVariables == nil {\n\t\tb.EnvironmentVariables = funcEmptyString\n\t}","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/resources/nodeup.go#L280-L316","documentation":"escapeBlobLocation parses the Azure Blob URL with url.Parse; this error is thrown when parsing itself fails, before any scheme/shape validation. The wrapped error from url.Parse identifies the exact syntax problem.","triggerScenarios":"A nodeup source location with the azureblob:// scheme that fails Go's url.Parse, e.g. invalid percent-encodings, control characters, or an unparseable host portion.","commonSituations":"Pasting an https:// blob SAS URL with '?' SAS tokens and '&' into the azureblob source field, or embedding characters like spaces or stray brackets in the account/container/key path.","solutions":["Fix the URL syntax per the wrapped url.Parse message.","Use the canonical form azureblob://<account>/<container>/<key> with percent-encoding for special characters in the key.","Strip SAS tokens/queries — pass credentials out of band, not in the source URL.","Test with url.Parse in a scratch Go program before applying."],"exampleFix":"// before\nNodeUpSource: \"azureblob://myaccount/container/path with space/nodeup\"\n// after\nNodeUpSource: \"azureblob://myaccount/container/path%20with%20space/nodeup\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(location)\nif err != nil {\n    return fmt.Errorf(\"azureblob location not a valid URL: %w\", err)\n}","typeGuard":"func parsesAsURL(s string) bool { _, err := url.Parse(s); return err == nil }","tryCatchPattern":"escaped, err := escapeBlobLocation(loc)\nif err != nil {\n    return fmt.Errorf(\"fix azureblob:// URL syntax: %w\", err)\n}","preventionTips":["Never paste SAS/portal URLs; build azureblob://account/container/key form","Percent-encode keys with special characters","Strip query strings and fragments from copied URLs"],"tags":["azure","url-parsing","nodeup"],"backgroundTag":"invalid-url-location","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"}