Skip to content

Diagnose multi-cluster and tenant controllers

Use remote member connectivity when a DSO/DSJ cannot distribute work to another cluster. Use tenant controller ownership when a workload in a shared cluster has missing or competing autoscalers. Dashboard cluster connections alone do not register distributed-scaling members.

Set the central context, Agent namespace and distributed resource. Use distributedscaledjobs for a DSJ:

Terminal window
CENTRAL_CONTEXT=central
AGENT_NS=keda
WORKLOAD_NS=default
RESOURCE=distributedscaledobjects
NAME=example
kubectl --context "$CENTRAL_CONTEXT" get "$RESOURCE" "$NAME" -n "$WORKLOAD_NS" -o json | \
jq '{members: .spec.memberClusters, status: .status}'
kubectl --context "$CENTRAL_CONTEXT" get kedifyconfiguration -n "$AGENT_NS" -o json | \
jq '.items[] | {name: .metadata.name, clusters: .status.multiClusterStatus.clusters}'
kubectl --context "$CENTRAL_CONTEXT" get events -n "$AGENT_NS" --sort-by=.lastTimestamp
kubectl --context "$CENTRAL_CONTEXT" get events -n "$WORKLOAD_NS" --sort-by=.lastTimestamp
EvidenceCheck and remedy
Member absent from configuration statusConfirm its registration Secret and provider. A Dashboard connection does not create a member entry.
MultiClusterNameCollision eventTwo providers registered the same alias. Use the intended canonical member ID or remove the duplicate registration through its owner.
Certificate or authentication failureReplace expired/incorrect credentials through the registration source. Use the CA expiry metric and member status where supported by the installed Agent.
Forbidden responseCompare remote RBAC with the GitOps registration procedure; verify target namespace and resource permissions.
Timeout / connection refusedCheck the API server address, DNS and network path from the central controller. Success from a laptop does not prove controller reachability.
Connected member but no replicas/jobsInspect the DSO/DSJ status for scheduling, capacity and failover decisions; for DSJ, also check the KEDA raw-metrics prerequisite.

For per-member Secret registration, inspect names and key presence without printing credentials:

Terminal window
kubectl --context "$CENTRAL_CONTEXT" get secrets -n "$AGENT_NS" \
-l sigs.k8s.io/multicluster-runtime-kubeconfig=true -o json | \
jq '.items[] | {name: .metadata.name, keys: (.data | keys)}'

Each entry should contain kubeconfig. For file-provider registration, inspect the mounted Secret named in the registration guide. Correct the owning configuration, then repeat the status checks. Verify the expected Deployment or Jobs in the intended member context and namespace; do not blindly resubmit distributed jobs, which can duplicate work.

Inspect the affected workload and the Agent’s tenant inventory:

Terminal window
kubectl config current-context
NS=tenant-workloads
SO=example
kubectl get scaledobject "$SO" -n "$NS" -o json | \
jq '{annotations: .metadata.annotations, target: .spec.scaleTargetRef, status: .status}'
kubectl get hpa -n "$NS" -o json | \
jq '.items[] | {name: .metadata.name, target: .spec.scaleTargetRef, owners: .metadata.ownerReferences}'
kubectl get kedifyconfiguration -n keda -o json | \
jq '.items[] | {name: .metadata.name, tenants: .status.discoveredTenants}'
kubectl get events -n keda --field-selector reason=KedifyTenantConnectionNotReady
kubectl get events -n "$NS" --sort-by=.lastTimestamp

When KPA is installed, also run:

Terminal window
kubectl get kpa -n "$NS" -o json | \
jq '.items[] | {name: .metadata.name, target: .spec.scaleTargetRef, owners: .metadata.ownerReferences, status: .status}'
Tenant status / symptomAction
operatorReady: falseInspect the registered operatorDeploymentName with kubectl describe deployment and its rollout status in the tenant’s control-plane namespace.
tlsCertReady: false or configSynced: falseInspect tenant connection events and the paired KEDA certificate/service configuration. Follow installation verification.
KPA intended, but kpa.paired: falseCompare KEDA/KPA namespace watch sets and kpa.kedaMetricsAddress. Correct the Helm values for the mismatched pair.
kpa.operatorObserved: falseThe Agent has not inspected the operator configuration. Check Agent logs/access before treating this as intentionally disabled KPA.
Both an HPA and KPA target the workloadCheck autoscaling.kedify.io/class, ScalingGroup membership and overlapping tenant scopes. Restore one owner through the ScaledObject and installation values; use the KPA rollback procedure when reverting.
CPU/memory metrics unavailableRun kubectl top pods -n "$NS" --containers; repair the Kubernetes Metrics API path before changing scaler targets.

An intentionally HPA-only tenant can have kpa.enabled, kpa.controllerReady and kpa.paired all false. Do not treat those fields alone as a failure. Namespace scoping is not a complete hostile-tenant security boundary; see access and data boundaries.

Confirm the affected tenant connection becomes ready and exactly one intended autoscaler controls the target. Repeat a bounded demand test, comparing the source metric, desired replicas and ready workload capacity. For unresolved failures, collect diagnostics with central/member context names, affected tenant, resource names and timestamps, excluding credential values.