Skip to content

helm plugin does not work #7035

@dmitrii-malinovskii

Description

@dmitrii-malinovskii

Bug Report

What did you do?

# Install the Operator SDK CLI

~$ cd /tmp/
/tmp$ export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)
/tmp$ export OS=$(uname | awk '{print tolower($0)}')
/tmp$ export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/v1.42.0
/tmp$ curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  112M  100  112M    0     0  27.7M      0  0:00:04  0:00:04 --:--:-- 32.0M
/tmp$ gpg --keyserver keyserver.ubuntu.com --recv-keys 052996E2A20B5C7E
gpg: key 052996E2A20B5C7E: public key "Operator SDK (release) <cncf-operator-sdk@cncf.io>" imported
gpg: Total number processed: 1
gpg:               imported: 1
/tmp$ curl -LO ${OPERATOR_SDK_DL_URL}/checksums.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1106  100  1106    0     0   2329      0 --:--:-- --:--:-- --:--:--  2329
/tmp$ curl -LO ${OPERATOR_SDK_DL_URL}/checksums.txt.asc
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   566  100   566    0     0   1204      0 --:--:-- --:--:-- --:--:--  1204
/tmp$ gpg -u "Operator SDK (release) <cncf-operator-sdk@cncf.io>" --verify checksums.txt.asc
gpg: assuming signed data in 'checksums.txt'
gpg: Signature made Thu 13 Nov 2025 15:27:30 CET
gpg:                using RSA key 8613DB87A5BA825EF3FD0EBE2A859D08BF9886DB
gpg: Good signature from "Operator SDK (release) <cncf-operator-sdk@cncf.io>" [unknown]
gpg: Note: This key has expired!
Primary key fingerprint: 3B2F 1481 D146 2380 80B3  46BB 0529 96E2 A20B 5C7E
     Subkey fingerprint: 8613 DB87 A5BA 825E F3FD  0EBE 2A85 9D08 BF98 86DB
/tmp$ grep operator-sdk_${OS}_${ARCH} checksums.txt | sha256sum -c -
operator-sdk_linux_amd64: OK
/tmp$ chmod +x operator-sdk_${OS}_${ARCH} && sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk
/tmp$ operator-sdk version
operator-sdk version: "v1.42.0", commit: "ab5563df5499cafa4ea9d40d4b36b51899a4718e", kubernetes version: "1.33.1", go version: "go1.24.6", GOOS: "linux", GOARCH: "amd64"

# Quickstart for Go-based Operators

/tmp$ mkdir memcached-operator
/tmp$ cd memcached-operator
/tmp/memcached-operator$ operator-sdk init --domain example.com --repo github.com/example/memcached-operator
INFO[0000] Writing kustomize manifests for you to edit... 
INFO[0000] Writing scaffold for you to edit...          
INFO[0000] Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.21.0 
INFO[0002] Update dependencies:
$ go mod tidy           
go: downloading google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80
go: downloading github.com/grpc-ecosystem/grpc-gateway v1.16.0
Next: define a resource with:
$ operator-sdk create api
/tmp/memcached-operator$ operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource --controller
INFO[0000] Writing kustomize manifests for you to edit... 
INFO[0000] Writing scaffold for you to edit...          
INFO[0000] api/v1alpha1/memcached_types.go              
INFO[0000] api/v1alpha1/groupversion_info.go            
INFO[0000] internal/controller/suite_test.go            
INFO[0000] internal/controller/memcached_controller.go  
INFO[0000] internal/controller/memcached_controller_test.go 
INFO[0000] Update dependencies:
$ go mod tidy           
INFO[0000] Running make:
$ make generate                
mkdir -p /tmp/memcached-operator/bin
Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0
/tmp/memcached-operator/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
Next: implement your new API and generate the manifests (e.g. CRDs,CRs) with:
$ make manifests
/tmp/memcached-operator$ make test                                                                                              
/tmp/memcached-operator/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases                                            
/tmp/memcached-operator/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."                                                                                    
go fmt ./...                                                                                                                                                                            
go vet ./...                                                                                                                                                                            
Downloading sigs.k8s.io/controller-runtime/tools/setup-envtest@release-0.21                                                                                                             
Setting up envtest binaries for Kubernetes version 1.33...                                                                                                                              
/tmp/memcached-operator/bin/k8s/1.33.0-linux-amd64KUBEBUILDER_ASSETS="/tmp/memcached-operator/bin/k8s/1.33.0-linux-amd64" go test $(go list ./... | grep -v /e2e) -coverprofile cover.ou
t                                                                                                                                                                                       
        github.com/example/memcached-operator/api/v1alpha1              coverage: 0.0% of statements                                                                                    
        github.com/example/memcached-operator/cmd               coverage: 0.0% of statements                                                                                            
ok      github.com/example/memcached-operator/internal/controller       5.617s  coverage: 66.7% of statements                                                                           
        github.com/example/memcached-operator/test/utils                coverage: 0.0% of statements
/tmp/memcached-operator$ make test-e2e                                                                         15:07:47 [91/171]
No kind clusters found.                                                                                                                                                                 
Creating Kind cluster 'memcached-operator-test-e2e'...                                                                                                                                  
Creating cluster "memcached-operator-test-e2e" ...                                                                                                                                      
 ✓ Ensuring node image (kindest/node:v1.35.0) 🖼                                                                                                                                         
 ✓ Preparing nodes 📦                                                                                                                                                                   
 ✓ Writing configuration 📜                                                                                                                                                             
 ✓ Starting control-plane 🕹️                                                                                                                                                             
 ✓ Installing CNI 🔌                                                                                                                                                                    
 ✓ Installing StorageClass 💾                                                                                                                                                           
Set kubectl context to "kind-memcached-operator-test-e2e"                                                                                                                               
You can now use your cluster with:                                                                                                                                                      
                                                                                                                                                                                        
kubectl cluster-info --context kind-memcached-operator-test-e2e                                                                                                                         
                                                                                                                                                                                        
Thanks for using kind! 😊                                                                                                                                                               
/tmp/memcached-operator/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases                                            
/tmp/memcached-operator/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."                                                                                    
go fmt ./...
go vet ./...
KIND_CLUSTER=memcached-operator-test-e2e go test ./test/e2e/ -v -ginkgo.v
=== RUN   TestE2E
  Starting memcached-operator integration test suite
Running Suite: e2e suite - /tmp/memcached-operator/test/e2e
===========================================================
Random Seed: 1767362796

Will run 2 of 2 specs
------------------------------
[BeforeSuite]
[BeforeSuite]                                                                                                                                                          15:07:52 [62/171]
/tmp/memcached-operator/test/e2e/e2e_suite_test.go:55
  STEP: building the manager(Operator) image @ 01/02/26 15:06:36.177
  running: "make docker-build IMG=example.com/memcached-operator:v0.0.1"
  STEP: loading the manager(Operator) image on Kind @ 01/02/26 15:07:27.237
  running: "kind load docker-image example.com/memcached-operator:v0.0.1 --name memcached-operator-test-e2e"
  STEP: checking if cert manager is installed already @ 01/02/26 15:07:29.674
  running: "kubectl get crds"
  Installing CertManager...
  running: "kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.3/cert-manager.yaml"
  running: "kubectl wait deployment.apps/cert-manager-webhook --for condition=Available --namespace cert-manager --timeout 5m"
[BeforeSuite] PASSED [71.179 seconds]
------------------------------
Manager Manager should run successfully
/tmp/memcached-operator/test/e2e/e2e_test.go:141
  STEP: creating manager namespace @ 01/02/26 15:07:47.357
  running: "kubectl create ns memcached-operator-system"
  STEP: labeling the namespace to enforce the restricted security policy @ 01/02/26 15:07:47.399
  running: "kubectl label --overwrite ns memcached-operator-system pod-security.kubernetes.io/enforce=restricted"
  STEP: installing CRDs @ 01/02/26 15:07:47.444
  running: "make install"
  STEP: deploying the controller-manager @ 01/02/26 15:07:49.524
  running: "make deploy IMG=example.com/memcached-operator:v0.0.1"
  STEP: validating that the controller-manager pod is running as expected @ 01/02/26 15:07:50.284
  running: "kubectl get pods -l control-plane=controller-manager -o go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ e
nd }} -n memcached-operator-system"
  running: "kubectl get pods memcached-operator-controller-manager-7cc576dd55-d7bqk -o jsonpath={.status.phase} -n memcached-operator-system"
  running: "kubectl get pods -l control-plane=controller-manager -o go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ e
nd }} -n memcached-operator-system"
  running: "kubectl get pods memcached-operator-controller-manager-7cc576dd55-d7bqk -o jsonpath={.status.phase} -n memcached-operator-system"
• [4.100 seconds]
------------------------------
Manager Manager should ensure the metrics endpoint is serving metrics                                                                                                  15:08:08 [30/171]
/tmp/memcached-operator/test/e2e/e2e_test.go:173
  STEP: creating a ClusterRoleBinding for the service account to allow access to metrics @ 01/02/26 15:07:51.457
  running: "kubectl create clusterrolebinding memcached-operator-metrics-binding --clusterrole=memcached-operator-metrics-reader --serviceaccount=memcached-operator-system:memcached-op
erator-controller-manager"
  STEP: validating that the metrics service is available @ 01/02/26 15:07:51.504
  running: "kubectl get service memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  STEP: getting the service account token @ 01/02/26 15:07:51.545
  STEP: waiting for the metrics endpoint to be ready @ 01/02/26 15:07:51.587
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  running: "kubectl get endpoints memcached-operator-controller-manager-metrics-service -n memcached-operator-system"
  STEP: verifying that the controller manager is serving the metrics server @ 01/02/26 15:08:03.141
  running: "kubectl logs memcached-operator-controller-manager-7cc576dd55-d7bqk -n memcached-operator-system"
  STEP: creating the curl-metrics pod to access the metrics endpoint @ 01/02/26 15:08:03.19
  running: "kubectl run curl-metrics --restart=Never --namespace memcached-operator-system --image=curlimages/curl:latest --overrides {\n\t\t\t\t\t\"spec\": {\n\t\t\t\t\t\t\"containers
\": [{\n\t\t\t\t\t\t\t\"name\": \"curl\",\n\t\t\t\t\t\t\t\"image\": \"curlimages/curl:latest\",\n\t\t\t\t\t\t\t\"command\": [\"/bin/sh\", \"-c\"],\n\t\t\t\t\t\t\t\"args\": [\"curl -v -
k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6InltZWV4QUZDaHV2SkRrQloydTNOMkdnaGhqWVpnRFUwdVJHTUtrQ3hQN2sifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIub
G9jYWwiXSwiZXhwIjoxNzY3MzY2NDcxLCJpYXQiOjE3NjczNjI4NzEsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZjYzYjgyMDEtMzNmMi00NjQ3LWJkMWEtMmVkY2ExMGVjZjU4I
iwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJtZW1jYWNoZWQtb3BlcmF0b3Itc3lzdGVtIiwic2VydmljZWFjY291bnQiOnsibmFtZSI6Im1lbWNhY2hlZC1vcGVyYXRvci1jb250cm9sbGVyLW1hbmFnZXIiLCJ1aWQiOiIzYjY3NzQ4N
C04ZjNjLTQ5NTgtOWVjMS00YTNlOWY3YzFkODAifX0sIm5iZiI6MTc2NzM2Mjg3MSwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Om1lbWNhY2hlZC1vcGVyYXRvci1zeXN0ZW06bWVtY2FjaGVkLW9wZXJhdG9yLWNvbnRyb2xsZXItbWFuY
WdlciJ9.Vi1ex_XdQa27qZ3RfxH98XOjghvjXqNDeGIyUpDnudDKXOqtjEDI-jrNmnhLtsq4ypWGWOUW7HNLdr99Icwi2PQXblqC4UtvxP3ghxHhlF1DSUv6QCq60A1u2zdRalq7SxgWc5StXueop96HeRVJi6IsCnalM7hYTf8qcbZaAgKjli06
TfU127739fPgWZaF0yJNj8Q62ybBUN7TAllHALXmCZH4kG5bnJjPILx4ejZfeKE8H7Qm7-5qfkiuWKXm0dRPL3RNLKjp5YhhsbL2jeDH8S5UlfHAwbGqoMai7eELAdN8RJorrk_b5ClaWwkxS-SOOCteQ31SMz-kfl2hgg' https://memcache
d-operator-controller-manager-metrics-service.memcached-operator-system.svc.cluster.local:8443/metrics\"],\n\t\t\t\t\t\t\t\"securityContext\": {\n\t\t\t\t\t\t\t\t\"allowPrivilegeEscala
tion\": false,\n\t\t\t\t\t\t\t\t\"capabilities\": {\n\t\t\t\t\t\t\t\t\t\"drop\": [\"ALL\"]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"runAsNonRoot\": true,\n\t\t\t\t\t\t\t\t\"runAsUser\": 
1000,\n\t\t\t\t\t\t\t\t\"seccompProfile\": {\n\t\t\t\t\t\t\t\t\t\"type\": \"RuntimeDefault\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}],\n\t\t\t\t\t\t\"serviceAccount\": \"mem
cached-operator-controller-manager\"\n\t\t\t\t\t}\n\t\t\t\t}"
  STEP: waiting for the curl-metrics pod to complete. @ 01/02/26 15:08:03.237
  running: "kubectl get pods curl-metrics -o jsonpath={.status.phase} -n memcached-operator-system"
  running: "kubectl get pods curl-metrics -o jsonpath={.status.phase} -n memcached-operator-system"
  running: "kubectl get pods curl-metrics -o jsonpath={.status.phase} -n memcached-operator-system"
  running: "kubectl get pods curl-metrics -o jsonpath={.status.phase} -n memcached-operator-system"
  running: "kubectl get pods curl-metrics -o jsonpath={.status.phase} -n memcached-operator-system"
  running: "kubectl get pods curl-metrics -o jsonpath={.status.phase} -n memcached-operator-system"
  STEP: getting the metrics by checking curl-metrics logs @ 01/02/26 15:08:08.514
  STEP: getting the curl-metrics logs @ 01/02/26 15:08:08.514
  running: "kubectl logs curl-metrics -n memcached-operator-system"
  STEP: cleaning up the curl pod for metrics @ 01/02/26 15:08:08.567
  running: "kubectl delete pod curl-metrics -n memcached-operator-system"
  STEP: undeploying the controller-manager @ 01/02/26 15:08:08.621
  running: "make undeploy"
  STEP: uninstalling CRDs @ 01/02/26 15:08:14.643
  running: "make uninstall"
  STEP: removing manager namespace @ 01/02/26 15:08:15.122
  running: "kubectl delete ns memcached-operator-system"
• [23.706 seconds]
------------------------------
[AfterSuite] 
/tmp/memcached-operator/test/e2e/e2e_suite_test.go:83
  Uninstalling CertManager...
  running: "kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.3/cert-manager.yaml"
[AfterSuite] PASSED [12.989 seconds]
------------------------------

Ran 2 of 2 Specs in 111.975 seconds
SUCCESS! -- 2 Passed | 0 Failed | 0 Pending | 0 Skipped
--- PASS: TestE2E (111.98s)
PASS
ok      github.com/example/memcached-operator/test/e2e  111.980s
make cleanup-test-e2e
make[1]: Entering directory '/tmp/memcached-operator'
Deleting cluster "memcached-operator-test-e2e" ...
Deleted nodes: ["memcached-operator-test-e2e-control-plane"]
make[1]: Leaving directory '/tmp/memcached-operator'

# I want to deploy this project using Helm, let's look at the readme..

/tmp/memcached-operator$ grep -m 1 -C 10 "helm" README.md | sed 's/^/    /'
    
    Users can just run 'kubectl apply -f <URL for YAML BUNDLE>' to install
    the project, i.e.:
    
    ```sh
    kubectl apply -f https://raw.githubusercontent.com/<org>/memcached-operator/<tag or branch>/dist/install.yaml
    ```
    
    ### By providing a Helm Chart
    
    1. Build the chart using the optional helm plugin
    
    ```sh
    operator-sdk edit --plugins=helm/v1-alpha
    ```
    
    2. See that a chart was generated under 'dist/chart', and users
    can obtain this solution from there.
    
    **NOTE:** If you change the project, you need to update the Helm Chart
    using the same command above to sync the latest changes. Furthermore,

# Nice! Let's try it.

/tmp/memcached-operator$ operator-sdk edit --plugins=helm/v1-alpha
Error: no plugin could be resolved with key "helm/v1-alpha" for project version "3" (plugin version is unstable, there may be an upgrade available: https://kubebuilder.io/migration/plugin/plugins.html)
Usage:
  operator-sdk [flags]

Examples:
The first step is to initialize your project:
    operator-sdk init [--plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]]

<PLUGIN KEYS> is a comma-separated list of plugin keys from the following table
and <PROJECT VERSION> a supported project version for these plugins.

                             Plugin keys | Supported project versions
-----------------------------------------+----------------------------
     ansible.sdk.operatorframework.io/v1 |                          3
 deploy-image.go.kubebuilder.io/v1-alpha |                          3
                    go.kubebuilder.io/v4 |                          3
         grafana.kubebuilder.io/v1-alpha |                          3
        helm.sdk.operatorframework.io/v1 |                          3

For more specific help for the init command of a certain plugins and project version
configuration please run:
    operator-sdk init --help --plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]

Default plugin keys: "go.kubebuilder.io/v4"
Default project version: "3"


Flags:
  -h, --help                     help for operator-sdk
      --plugins strings          plugin keys to be used for this subcommand execution
      --project-version string   project version (default "3")

FATA[0000] error executing command: no plugin could be resolved with key "helm/v1-alpha" for project version "3" (plugin version is unstable, there may be an upgrade available: https://kubebuilder.io/migration/plugin/plugins.html)

# This makes me sad.

/tmp/memcached-operator$ rm $(which operator-sdk)

What did you expect to see?

I expect to receive a helm chart as README.md says.

What did you see instead? Under which circumstances?

Just read the shell dump above. Pay attention to comments.

Environment

Operator type:

/language go

Kubernetes cluster type:

kind by running make test-e2e

$ operator-sdk version

operator-sdk version: "v1.42.0", commit: "ab5563df5499cafa4ea9d40d4b36b51899a4718e", kubernetes version: "1.33.1", go version: "go1.24.6", GOOS: "linux", GOARCH: "amd64"

$ go version (if language is Go)

go version go1.25.5 linux/amd64

$ kubectl version

Client Version: v1.34.1
Kustomize Version: v5.7.1
The connection to the server localhost:8080 was refused - did you specify the right host or port?

Possible Solution

Either fix the command operator-sdk edit --plugins=helm/v1-alpha or remove it from the readme.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    language/goIssue is related to a Go operator projectlifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions