{"record":{"id":"8de5d5f7028febf7","repo":"kubernetes/kops","slug":"error-listing-secrets-directory-v","errorCode":null,"errorMessage":"error listing secrets directory: %v","messagePattern":"error listing secrets directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/secrets/vfs_secretstore.go","lineNumber":105,"sourceCode":"\treturn nil\n}\n\n// DeleteSecret implements fi.SecretStore DeleteSecret\nfunc (c *VFSSecretStore) DeleteSecret(name string) error {\n\tctx := context.TODO()\n\n\tp := c.buildSecretPath(name)\n\treturn p.Remove(ctx)\n}\n\nfunc (c *VFSSecretStore) ListSecrets() ([]string, error) {\n\tfiles, err := c.basedir.ReadDir()\n\tvar ids []string\n\tif os.IsNotExist(err) {\n\t\treturn ids, nil\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing secrets directory: %v\", err)\n\t}\n\tfor _, f := range files {\n\t\tid := f.Base()\n\t\tids = append(ids, id)\n\t}\n\treturn ids, nil\n}\n\nfunc (c *VFSSecretStore) GetOrCreateSecret(ctx context.Context, id string, secret *fi.Secret) (*fi.Secret, bool, error) {\n\tp := c.buildSecretPath(id)\n\n\tfor i := 0; i < 2; i++ {\n\t\ts, err := c.FindSecret(id)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\n\t\tif s != nil {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/secrets/vfs_secretstore.go#L87-L123","documentation":"ListSecrets enumerates the store by calling ReadDir on the secrets basedir. A missing directory is treated as an empty list (os.IsNotExist is tolerated), but any other ReadDir failure is wrapped as 'error listing secrets directory'. This wraps all storage-level read errors from the underlying VFS implementation.","triggerScenarios":"ReadDir fails for reasons other than NotExist: permission denied on the bucket/prefix, network timeout to object storage, invalid VFS path scheme, or a HEAD/LIST API error from S3/GCS.","commonSituations":"Expired AWS session tokens, IAM policy without s3:ListBucket on the secrets prefix, offline/VPN-down workstation against a remote state store, misconfigured KOPS_STATE_STORE URL.","solutions":["Run `kops get secrets` to reproduce and see the raw cause","Fix credentials/IAM: ensure list permission on the secrets prefix","Verify connectivity to the storage backend (proxy, VPN, DNS)","Correct KOPS_STATE_STORE / basedir if the path is malformed"],"exampleFix":"// before: missing ListBucket permission\nsecrets, err := store.ListSecrets() // error listing secrets directory: ListObjects AccessDenied\n// after: attach policy granting s3:ListBucket on the secrets bucket\n// aws iam attach-role-policy --role-name kops --policy-arn arn:aws:iam::...:policy/kops-list\nsecrets, err := store.ListSecrets()","handlingStrategy":"try-catch","validationCode":"// Confirm listing works before depending on it\nids, err := store.ListSecrets()\nif err != nil { return fmt.Errorf(\"fix storage access first: %v\", err) }","typeGuard":null,"tryCatchPattern":"ids, err := store.ListSecrets()\nif err != nil {\n    if strings.Contains(err.Error(), \"error listing secrets directory\") {\n        // missing-dir is tolerated upstream; treat as storage/permission issue\n        return diagnoseVFSAccess(store.VFSPath(), err)\n    }\n    return err\n}","preventionTips":["Ensure list permission on the state store prefix (s3:ListBucket)","Check network/VPN before remote kops operations","Validate KOPS_STATE_STORE URL scheme and bucket existence","Refresh expiring credentials in CI before each run"],"tags":["vfs","secrets","storage","listing"],"backgroundTag":"vfs-list-failed","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"}