istio/istio · error

configmap access not enabled for remote clusters

Error message

configmap access not enabled for remote clusters

What it means

Returned by CredentialsController.GetConfigMapCaCert when called on a controller constructed with isConfigCluster=false. NewCredentialsController sets that flag only for the config cluster (see multicluster.go: remote clusters get isConfigCluster=false), because the istio-ca-root-cert ConfigMap is only authoritative/readable there. The method refuses immediately rather than performing a doomed lookup.

Source

Thrown at pilot/pkg/credentials/kube/secrets.go:244

}

func (s *CredentialsController) GetCaCert(name, namespace string) (certInfo *credentials.CertInfo, err error) {
	k8sSecret := s.secrets.Get(name, namespace)
	if k8sSecret == nil {
		strippedName := strings.TrimSuffix(name, securitymodel.SdsCaSuffix)
		// Could not fetch cert, look for secret without -cacert suffix
		k8sSecret := s.secrets.Get(strippedName, namespace)
		if k8sSecret == nil {
			return nil, fmt.Errorf("secret %v/%v not found", namespace, strippedName)
		}
		return ExtractRoot(k8sSecret.Data)
	}
	return ExtractRoot(k8sSecret.Data)
}

func (s *CredentialsController) GetConfigMapCaCert(name, namespace string) (certInfo *credentials.CertInfo, err error) {
	if !s.isConfigCluster {
		return nil, fmt.Errorf("configmap access not enabled for remote clusters")
	}
	strippedName := strings.TrimSuffix(name, securitymodel.SdsCaSuffix)
	cm := s.configMaps.Get(strippedName, namespace)
	if cm == nil {
		return nil, fmt.Errorf("configmap %v/%v not found", namespace, strippedName)
	}

	return ExtractRootFromString(cm.Data)
}

func (s *CredentialsController) GetDockerCredential(name, namespace string) ([]byte, error) {
	k8sSecret := s.secrets.Get(name, namespace)
	if k8sSecret == nil {
		return nil, fmt.Errorf("secret %v/%v not found", namespace, name)
	}
	if k8sSecret.Type != v1.SecretTypeDockerConfigJson {
		return nil, fmt.Errorf("type of secret %v/%v is not %v", namespace, name, v1.SecretTypeDockerConfigJson)
	}

View on GitHub (pinned to 8dc789c5cf)

Solutions

  1. Route ConfigMap CA lookups to the config cluster's controller (the aggregate does this automatically when the config cluster is registered)
  2. Ensure the config cluster credentials controller exists (see cluster-not-configured / no-controllers errors) so the aggregate has a valid member
  3. For custom CAs on remote clusters, supply a Secret instead — secrets work on any cluster with the remote controller enabled
Defensive patterns

Strategy: validation

Validate before calling

// Only route ConfigMap CA requests to a config-cluster controller.
if !isConfigCluster {
    return nil, fmt.Errorf("skip configmap CA lookup on cluster %v; use config cluster", clusterID)
}
info, err := ctrl.GetConfigMapCaCert(name, namespace)

Prevention

When it happens

Trigger: Requesting a ConfigMap-based root CA (resource name typically the istio-ca-root-cert configmap, often via a '-cacert' style SDS name) through a credentials controller bound to a remote cluster. In the AggregateController the config cluster's controller normally answers, so the raw error surfaces when the aggregate contains only remote controllers or the type is asserted directly.

Common situations: Multicluster meshes where the CA root lookup is routed to the proxy's remote cluster; ENABLE_REMOTE_CREDENTIALS_CONTROLLER combinations that leave only remote controllers in the aggregate; code/tests calling GetConfigMapCaCert directly on a remote-cluster controller.

Related errors


AI-assisted analysis of istio/istio@8dc789c5cf (2026-08-15). Data as JSON: /api/errors/f713cbdcf1e99dee. Report an issue: GitHub.