kubernetes/kops · error
locationStore=%q is of unexpected type %T
Error message
locationStore=%q is of unexpected type %T
What it means
After parsing discoveryStore, kOps switches on the concrete VFS path type and only supports S3 and MemFS paths. Any other store type (file://, gs://, azblob://, etc.) hits the default branch and returns this 'unexpected type' error with the Go type in the message.
Source
Thrown at pkg/model/components/discovery.go:76
switch base := base.(type) {
case *vfs.S3Path:
serviceAccountIssuer, err = base.GetHTTPsUrl(clusterSpec.IsIPv6Only())
if err != nil {
return err
}
case *vfs.GSPath:
serviceAccountIssuer, err = base.GetHTTPsUrl()
if err != nil {
return err
}
case *vfs.MemFSPath:
if !base.IsClusterReadable() {
// If this _is_ a test, we should call MarkClusterReadable
return fmt.Errorf("locationStore=%q is only supported in tests", store)
}
serviceAccountIssuer = strings.Replace(base.Path(), "memfs://", "https://", 1)
default:
return fmt.Errorf("locationStore=%q is of unexpected type %T", store, base)
}
} else if said != nil && said.DiscoveryService != nil {
discoveryService := said.DiscoveryService
serviceAccountIssuer = discoveryService.URL
if serviceAccountIssuer == "" {
return fmt.Errorf("discoveryService URL must be specified")
}
} else {
if supportsPublicJWKS(clusterSpec) && clusterSpec.API.PublicName != "" {
serviceAccountIssuer = "https://" + clusterSpec.API.PublicName
} else {
serviceAccountIssuer = "https://api.internal." + b.ClusterName
}
}
kubeAPIServer.ServiceAccountIssuer = &serviceAccountIssuer
}
kubeAPIServer.ServiceAccountJWKSURI = new(*kubeAPIServer.ServiceAccountIssuer + "/openid/v1/jwks")View on GitHub (pinned to 4c8573c808)
Solutions
- Use an S3 path (s3://...) for discoveryStore
- Or omit discoveryStore and rely on the default issuer (https://api.<clustername> / API public name)
- Add support for the desired VFS type in pkg/model/components/discovery.go if you control the fork
Example fix
// before serviceAccountIssuerDiscovery: discoveryStore: "gs://my-bucket/discovery" // after serviceAccountIssuerDiscovery: discoveryStore: "s3://my-bucket/discovery"
Defensive patterns
Strategy: type-guard
Validate before calling
base, err := vfs.Context.BuildVfsPath(store)
if err == nil {
switch base.(type) {
case *vfs.S3Path, *vfs.MemFSPath:
default:
return fmt.Errorf("discoveryStore %s must be an S3 path", store)
}
} Type guard
func isSupportedDiscoveryPath(base vfs.VFSPath) bool {
switch base.(type) {
case *vfs.S3Path, *vfs.MemFSPath:
return true
}
return false
} Try / catch
if err := buildOptions(); err != nil {
if strings.Contains(err.Error(), "unexpected type") {
// switch discoveryStore to s3:// in the spec
}
return err
} Prevention
- Only use s3:// for discoveryStore today
- Consult the discovery.go switch for supported types before choosing a store
- Document supported backends in cluster templates
When it happens
Trigger: Setting discoveryStore to a supported-by-VFS-but-unsupported-for-discovery path type such as file:// or gs:// while BuildOptions runs.
Common situations: Assuming any object store works for issuer discovery when only S3 is implemented; porting configs between clouds.
Related errors
- error parsing locationStore=%q: %w
- cannot parse ConfigBase %q: %w
- no keypair ID for %q
- error parsing path for etcd manifest %s: %v
- error parsing ConfigStore.Base %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/53c3e589e5a5bcf4.
Report an issue: GitHub.