kubernetes/kops · error
error reading directory %q: %v
Error message
error reading directory %q: %v
What it means
VFSCAStore.ListKeysets reads the entire tree under <state-store>/<cluster>/private via vfs ReadTree to discover keysets. If the underlying storage (S3/GCS/etc.) read fails — permissions, missing bucket, network issues — the error is wrapped as "error reading directory" with the base path.
Source
Thrown at upup/pkg/fi/vfs_castore.go:165
if !ok {
klog.Fatalf("no YAML serializer registered")
}
encoder := codecs.EncoderForVersion(yaml.Serializer, v1alpha2.SchemeGroupVersion)
if err := encoder.Encode(o, &objectData); err != nil {
return nil, fmt.Errorf("error serializing keyset: %v", err)
}
return objectData.Bytes(), nil
}
// ListKeysets implements CAStore::ListKeysets
func (c *VFSCAStore) ListKeysets() (map[string]*Keyset, error) {
ctx := context.TODO()
baseDir := c.basedir.Join("private")
files, err := baseDir.ReadTree(ctx)
if err != nil {
return nil, fmt.Errorf("error reading directory %q: %v", baseDir, err)
}
keysets := map[string]*Keyset{}
for _, f := range files {
relativePath, err := vfs.RelativePath(baseDir, f)
if err != nil {
return nil, err
}
tokens := strings.Split(relativePath, "/")
if len(tokens) != 2 || tokens[1] != "keyset.yaml" {
klog.V(2).Infof("ignoring unexpected file in keystore: %q", f)
continue
}
name := tokens[0]
loadedKeyset, err := c.loadKeyset(ctx, baseDir.Join(name))View on GitHub (pinned to 4c8573c808)
Solutions
- Verify KOPS_STATE_STORE/--state points to an existing, correctly-spelled bucket/path.
- Check cloud credentials and IAM permissions for listing/reading objects in the bucket.
- Confirm network access to the storage endpoint and correct region configuration.
- Run `kops get clusters` against the same state store to isolate whether the path or permissions are the problem.
Example fix
// before export KOPS_STATE_STORE=s3://kops-state-backup # bucket does not exist // after export KOPS_STATE_STORE=s3://my-kops-state # existing bucket with read access
Defensive patterns
Strategy: retry
Validate before calling
// Verify the state store is readable before listing
ctx := context.TODO()
if _, err := vfs.Context.ReadLocation(os.Getenv("KOPS_STATE_STORE")).Join(cluster.Name).Join("config").ReadFile(ctx); err != nil {
return fmt.Errorf("state store unreadable: %w", err)
} Try / catch
keysets, err := store.ListKeysets()
if err != nil {
if strings.Contains(err.Error(), "error reading directory") {
// check creds/bucket, optionally retry with backoff
return retryWithBackoff(func() error { _, e := store.ListKeysets(); return e })
}
return err
} Prevention
- Pin KOPS_STATE_STORE in CI and verify bucket existence in a preflight step.
- Grant least-privilege read (List/Get) IAM policies to the identity running kops.
- Handle transient cloud-storage errors with exponential backoff.
When it happens
Trigger: Calling ListKeysets (or MirrorTo which uses related listing) when the state store path is inaccessible: bucket does not exist, credentials lack s3:ListBucket/GetObject, region mismatch, network outage, or the VFS path is misconfigured.
Common situations: Running `kops get secrets`/mirror commands with wrong --state or KOPS_STATE_STORE; IAM policies changed or creds expired; offline/blocked network access to the cloud storage endpoint; typo'd bucket name.
Related errors
- error reading state store: %v
- error reading %s %q: %v
- error writing %s: %v
- error reading %s: %v
- error checking if configuration file %s exists already: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5406c3bdac259d4c.
Report an issue: GitHub.