ServiceMonitor has 3 conditions to be populated, make sure that your cluster and configs meet these conditions: https://github.com/kubernetes/ingress-nginx/blob/6299c39842c31ff1e17d72503003ca36e2976a9a/charts/ingress-nginx/templates/controller-servicemonitor.yaml#L1
your cluster should support: monitoring.coreos.com/v1 API version
if you use an older chart version where the API condition is not there, you will be able to deploy the ServiceMonitor with your current values.yaml
helm template ingress-nginx/ingress-nginx --values values.yaml --version "3.15.2" | grep -i mon
# Source: ingress-nginx/templates/controller-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
Also, note that: https://helm.sh/docs/helm/helm_template/
Render chart templates locally and display the output.
Any values that would normally be looked up or retrieved in-cluster will be faked locally. Additionally, none of the server-side testing of chart validity (e.g. whether an API is supported) is done.
This means if you run the command line on your machine, it will never show the ServiceMonitor
unless you have a local k8s cluster that supports monitoring.coreos.com/v1
or you fake it too :) as below
helm template ingress-nginx/ingress-nginx --values values.yaml --version "4.0.5" --api-versions "monitoring.coreos.com/v1" | grep -i mon
# Source: ingress-nginx/templates/controller-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor