{"record":{"id":"eede266ac93189e5","repo":"kubernetes/kops","slug":"invalid-azure-blob-scheme-q","errorCode":null,"errorMessage":"invalid Azure Blob scheme: %q","messagePattern":"invalid Azure Blob scheme: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/pkg/vfs/context.go","lineNumber":580,"sourceCode":"\tif bucket == \"\" {\n\t\treturn nil, fmt.Errorf(\"invalid swift path: %q\", p)\n\t}\n\n\treturn NewSwiftPath(c, bucket, u.Path)\n}\n\nfunc (c *VFSContext) buildAzureBlobPath(p string) (*AzureBlobPath, error) {\n\tif os.Getenv(\"AZURE_STORAGE_ACCOUNT\") != \"\" {\n\t\treturn nil, fmt.Errorf(\"unset AZURE_STORAGE_ACCOUNT; the storage account belongs in the URL:  azureblob://<account>/<container>/<key>\")\n\t}\n\n\tu, err := url.Parse(p)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse %q: %s\", p, err)\n\t}\n\n\tif u.Scheme != \"azureblob\" {\n\t\treturn nil, fmt.Errorf(\"invalid Azure Blob scheme: %q\", p)\n\t}\n\n\taccount := strings.TrimSuffix(u.Host, \"/\")\n\tif account == \"\" {\n\t\treturn nil, fmt.Errorf(\"no storage account specified in %q; expected azureblob://<account>/<container>/<key>\", p)\n\t}\n\n\trest := strings.TrimPrefix(u.Path, \"/\")\n\tcontainer, key, _ := strings.Cut(rest, \"/\")\n\tif container == \"\" {\n\t\treturn nil, fmt.Errorf(\"no container specified in %q; expected azureblob://<account>/<container>/<key>\", p)\n\t}\n\n\treturn NewAzureBlobPath(c, account, container, key), nil\n}\n\n// getAzureBlobClient returns the client for azure blob storage for the given\n// storage account, caching it for future reuse.","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/util/pkg/vfs/context.go#L562-L598","documentation":"buildAzureBlobPath enforces the azureblob:// scheme; any other scheme returns \"invalid Azure Blob scheme\". Because BuildVfsPath selects the builder from the scheme, reaching this check means a non-azureblob URL was handed to the Azure builder.","triggerScenarios":"BuildVfsPath with a URL whose parsed scheme is not exactly \"azureblob\" — e.g. azure://, azblob://, https:// storage endpoints, or a bare host-less string with empty scheme routed to this builder.","commonSituations":"Typo in scheme (\"azurblob://\"); using the generic https:// ARM endpoint instead of the azureblob:// VFS form; config examples from other tools (azcopy, SDK) that use different URL shapes.","solutions":["Change the scheme to exactly \"azureblob://<account>/<container>/<key>\"","Replace https:// ARM/resource-manager URLs with the azureblob:// VFS form","Fix scheme typos and ensure the prefix survives templating/joining","Let BuildVfsPath dispatch on scheme rather than calling buildAzureBlobPath with a foreign-scheme URL"],"exampleFix":"// before\ncontext.BuildVfsPath(\"azure://mystorage/container/state\")\n// after\ncontext.BuildVfsPath(\"azureblob://mystorage/container/state\")","handlingStrategy":"validation","validationCode":"u, err := url.Parse(stateStore); if err != nil || u.Scheme != \"azureblob\" { return fmt.Errorf(\"Azure state store must use azureblob:// scheme, got %q\", stateStore) }","typeGuard":"func isAzureBlobPath(p string) bool { u, err := url.Parse(p); return err == nil && u.Scheme == \"azureblob\" }","tryCatchPattern":"if _, err := context.BuildVfsPath(p); err != nil { if strings.Contains(err.Error(), \"invalid Azure Blob scheme\") { /* correct the scheme to azureblob:// and retry */ } return err }","preventionTips":["Use exactly azureblob://<account>/<container>/<key>, not azure:// or https://","Guard scheme strings against templating typos","Add a lint/CI rule asserting the state-store scheme per provider"],"tags":["azure","azureblob","url-scheme","vfs"],"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"}