{"record":{"id":"5df4a21688a67ed9","repo":"kubernetes/kops","slug":"unknown-writeable-path-can-t-apply-iam-policy-q","errorCode":null,"errorMessage":"unknown writeable path, can't apply IAM policy: %q","messagePattern":"unknown writeable path, can't apply IAM policy: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/iam/iam_builder.go","lineNumber":652,"sourceCode":"\n\tfor _, vfsPath := range writeablePaths {\n\t\tswitch path := vfsPath.(type) {\n\t\tcase *vfs.S3Path:\n\t\t\tiamS3Path := path.Bucket() + \"/\" + path.Key()\n\t\t\tiamS3Path = strings.TrimSuffix(iamS3Path, \"/\")\n\n\t\t\tb.buildS3WriteStatements(p, iamS3Path)\n\t\t\ts3Buckets.Insert(path.Bucket())\n\t\tcase *vfs.MemFSPath:\n\t\t\tiamS3Path := \"placeholder-write-bucket/\" + path.Location()\n\t\t\tb.buildS3WriteStatements(p, iamS3Path)\n\t\t\ts3Buckets.Insert(\"placeholder-write-bucket\")\n\t\tcase *vfs.FSPath:\n\t\t\tiamS3path := \"placeholder-read-bucket/\" + strings.TrimPrefix(path.Path(), \"file://\")\n\t\t\tb.buildS3WriteStatements(p, iamS3path)\n\t\t\ts3Buckets.Insert(\"placeholder-read-bucket\")\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown writeable path, can't apply IAM policy: %q\", vfsPath)\n\t\t}\n\t}\n\n\t// We need some permissions on the buckets themselves\n\tfor _, s3Bucket := range s3Buckets.List() {\n\t\tp.Statement = append(p.Statement, &Statement{\n\t\t\tEffect: StatementEffectAllow,\n\t\t\tAction: stringorset.Of(\n\t\t\t\t\"s3:GetBucketLocation\",\n\t\t\t\t\"s3:GetEncryptionConfiguration\",\n\t\t\t\t\"s3:ListBucket\",\n\t\t\t\t\"s3:ListBucketVersions\",\n\t\t\t),\n\t\t\tResource: stringorset.Set([]string{\n\t\t\t\tfmt.Sprintf(\"arn:%v:s3:::%v\", p.partition, s3Bucket),\n\t\t\t}),\n\t\t})\n\t}","sourceCodeStart":634,"sourceCodeEnd":670,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/iam/iam_builder.go#L634-L670","documentation":"In the writeable-path half of AddS3Permissions, kOps grants S3 write statements only for S3Path, MemFSPath and FSPath types returned by WriteableVFSPaths. If an etcd backupStore (or other writeable path) resolves to any other vfs.Path implementation, the builder cannot emit matching IAM statements and returns this error with the path quoted.","triggerScenarios":"NodeRoleMaster policy build where cluster.Spec.EtcdClusters[*].Backups.BackupStore parses (BuildVfsPath succeeded) into a vfs.Path that is not S3/MemFS/FS — e.g. a GCS or Azure backup store URL used with AWS master role IAM generation.","commonSituations":"etcd-manager backupStore copied from a GCE/Azure cluster into an AWS cluster spec; custom or future VFS backend for backups; hand-edited cluster spec with a typo'd scheme that still resolves via an unexpected path type.","solutions":["Inspect the quoted path in the error to find which backupStore is offending.","Change every etcdClusters backupStore to a valid s3:// URL in the AWS cluster spec via `kops edit cluster`.","If the backup store scheme is intentionally non-S3, AWS IAM policies cannot cover it — use S3 for backups on AWS clusters.","After fixing, rerun `kops update cluster` to regenerate the master IAM policy."],"exampleFix":"// before\nbackups:\n  backupStore: \"azure://backups/example.k8s.local\"\n// after\nbackups:\n  backupStore: \"s3://my-kops-bucket/backups/example.k8s.local\"","handlingStrategy":"validation","validationCode":"vp, err := vfs.Context.BuildVfsPath(backupStore)\nif err != nil { return err }\nswitch vp.(type) {\ncase *vfs.S3Path, *vfs.MemFSPath, *vfs.FSPath:\n    // supported for IAM write statements\ndefault:\n    return fmt.Errorf(\"unsupported writeable backup store %q\", backupStore)\n}","typeGuard":null,"tryCatchPattern":"if err := builder.AddS3Permissions(policy); err != nil {\n    if strings.Contains(err.Error(), \"unknown writeable path\") {\n        // fix etcd backupStore in cluster spec\n    }\n    return err\n}","preventionTips":["Keep etcd backupStore on s3:// for AWS clusters","Grep the cluster spec for non-s3 backupStore values before update","Validate with `kops get cluster -o yaml | grep backupStore`"],"tags":["aws","iam","s3","etcd","kops"],"backgroundTag":"vfs-path-parse-error","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"}