{"record":{"id":"cc314e93ca6045f2","repo":"kubernetes/kops","slug":"locationstore-q-is-only-supported-in-tests","errorCode":null,"errorMessage":"locationStore=%q is only supported in tests","messagePattern":"locationStore=%q is only supported in tests","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/components/discovery.go","lineNumber":72,"sourceCode":"\t\t\tbase, err := vfs.Context.BuildVfsPath(store)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error parsing locationStore=%q: %w\", store, err)\n\t\t\t}\n\t\t\tswitch base := base.(type) {\n\t\t\tcase *vfs.S3Path:\n\t\t\t\tserviceAccountIssuer, err = base.GetHTTPsUrl(clusterSpec.IsIPv6Only())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\tcase *vfs.GSPath:\n\t\t\t\tserviceAccountIssuer, err = base.GetHTTPsUrl()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\tcase *vfs.MemFSPath:\n\t\t\t\tif !base.IsClusterReadable() {\n\t\t\t\t\t// If this _is_ a test, we should call MarkClusterReadable\n\t\t\t\t\treturn fmt.Errorf(\"locationStore=%q is only supported in tests\", store)\n\t\t\t\t}\n\t\t\t\tserviceAccountIssuer = strings.Replace(base.Path(), \"memfs://\", \"https://\", 1)\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"locationStore=%q is of unexpected type %T\", store, base)\n\t\t\t}\n\t\t} else if said != nil && said.DiscoveryService != nil {\n\t\t\tdiscoveryService := said.DiscoveryService\n\n\t\t\tserviceAccountIssuer = discoveryService.URL\n\t\t\tif serviceAccountIssuer == \"\" {\n\t\t\t\treturn fmt.Errorf(\"discoveryService URL must be specified\")\n\t\t\t}\n\t\t} else {\n\t\t\tif supportsPublicJWKS(clusterSpec) && clusterSpec.API.PublicName != \"\" {\n\t\t\t\tserviceAccountIssuer = \"https://\" + clusterSpec.API.PublicName\n\t\t\t} else {\n\t\t\t\tserviceAccountIssuer = \"https://api.internal.\" + b.ClusterName\n\t\t\t}","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/components/discovery.go#L54-L90","documentation":"If DiscoveryStore resolves to a vfs.MemFSPath that has not been marked cluster-readable, the issuer URL cannot be used outside of tests. kOps returns this error to indicate memfs discovery stores are only valid in unit tests after calling MarkClusterReadable.","triggerScenarios":"A cluster spec with serviceAccountIssuerDiscovery.discoveryStore pointing at memfs:// in a real (non-test) build, or a test that built a MemFSPath without calling MarkClusterReadable.","commonSituations":"Leftover test configuration (memfs) applied to a real cluster; unit test forgetting MarkClusterReadable before BuildOptions.","solutions":["In tests, call base.MarkClusterReadable() on the MemFSPath before building options","For real clusters, replace memfs:// discoveryStore with a real object store (e.g. s3://) so an HTTPS issuer URL can be derived"],"exampleFix":"// before\nvfs.Context.WriteFile(\"memfs://discovery/jwks\", data, 0644)\n// after\np := vfs.Context.ReadFile(\"memfs://discovery/jwks\") // MemFSPath\np.(*vfs.MemFSPath).MarkClusterReadable()","handlingStrategy":"type-guard","validationCode":"if strings.HasPrefix(store, \"memfs://\") && !isTest {\n    return fmt.Errorf(\"memfs discoveryStore is only for tests\")\n}","typeGuard":"func isClusterReadableMemFS(base vfs.VFSPath) bool {\n    m, ok := base.(*vfs.MemFSPath)\n    return ok && m.IsClusterReadable()\n}","tryCatchPattern":"if err := buildOptions(); err != nil {\n    if strings.Contains(err.Error(), \"is only supported in tests\") {\n        // call MarkClusterReadable on the MemFSPath and retry\n    }\n    return err\n}","preventionTips":["Never ship memfs:// discoveryStore in real cluster specs","In tests, always call MarkClusterReadable before BuildOptions","Add CI checks rejecting memfs in production manifests"],"tags":["config","memfs","tests","service-account"],"backgroundTag":"memfs-not-supported-outside-tests","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"}