Skip to main content
This guide helps you diagnose and resolve issues when rightsizing does not happen as expected. Prerequisites: Many diagnostic commands in this guide use jq for JSON parsing. Install with: apt-get install jq (Debian/Ubuntu), brew install jq (macOS), or yum install jq (RHEL/CentOS).

Troubleshooting Approach

The controller provides multiple levels of diagnostic information. Use them in this order:
  1. Start with annotations - Check the automation-constraints annotation on the pod to see blockers and filters
  2. Check summary logs - View rightsizing summary logs to understand evaluation outcomes
  3. Review events - Look for PrecheckFailed or policy evaluation events for patterns
  4. Verify configuration - Check GlobalConfiguration, policies, and strategies for misconfigurations
When to use what:
  • Annotations (automation-constraints, rollback-state) - Best for understanding why a specific pod is blocked right now
  • Summary logs - Best for seeing evaluation history and understanding what the controller attempted
  • Events - Best for identifying patterns across multiple pods or tracking timeline of actions
  • Debug logging - Only needed for controller internal issues or when requested by support
Most issues can be diagnosed using annotations and summary logs without enabling debug logging. For a consolidated map of the controller’s safety gates, see Safety Controls. For annotation configuration details, see Advanced Configuration Guide.

Quick Troubleshooting Decision Tree

Automation not happening? Follow this path:
  1. Check automation-constraints annotation on the pod (easiest & fastest) → See Understanding Annotations
    Alternative: Check rightsizing summary logs for evaluation history → See Interpret Rightsizing Summary Logs
    • Logs show BLOCKED? → Check failedChecks array for blocker names
    • Logs show SKIPPED? → All actions were filtered or no recommendations available
    • No logs for your pod? → Policy may not match, or controller may not be running
    • When to use logs: When you need historical context or the pod no longer exists
  2. Check if recommendations exist on the pod
    • No recommendations? → Verify policy configuration and recommendation sync
  3. Still stuck?
Everything looks fine but nothing happens? Common causes:
  • Recommendations match current state (no drift to correct)
  • Pod resources already match desired values
  • All containers are filtered by skip-containers annotation
  • Policy evaluation hasn’t run yet (check evaluation interval in AutomationStrategy)

Understanding Annotations for Troubleshooting

When troubleshooting, you’ll encounter annotations on both pod owners (Deployment, StatefulSet, etc.) and pods themselves. Understanding where annotations appear and what they mean is essential for diagnosis.

Pod Owner vs Pod: What’s the Difference?

Pod Owner = The workload resource that creates and manages pods:
  • Deployment, StatefulSet, DaemonSet, Job, CronJob, ReplicaSet, StrimziPodSet
Pod = The actual running pod instance created by the owner

Which Annotations Appear Where?

Notes:
  • pause-until & skip-containers: Owner annotations are automatically copied to pods. Check inherited-control-state to see if managed by controller.
  • desired-resource-requests & limits: Recommendations written to pods. Static policies also write to owners. Policy prefix indicates source.
  • automation-constraints: Most important for troubleshooting - shows why automation is blocked or what filters are active. Contains reasons[] array.
  • rollback-state: Rollback tracking happens at owner level only. Shows monitoring/backoff state.
  • inherited-control-state: Indicates pause/skip was inherited from owner and is managed by controller.

Interpreting Control Annotations (Pause & Skip)

When you see rightsizing.kubex.ai/pause-until or rightsizing.kubex.ai/skip-containers:

On Pod Owner (Deployment, StatefulSet, etc.)

What this means: You (or another user) set this on the owner. The controller will copy it to all pods managed by this owner.

On Pod

Interpretation:
  • inherited-control-state present: Pause was inherited from the owner. Controller manages this automatically and will remove it when you remove it from the owner.
  • inherited-control-state absent: Pause was set directly on the pod (rare). Controller won’t remove it automatically.
Troubleshooting tip - If a pause annotation isn’t clearing when expected:
  1. Check if it’s still on the pod owner (Deployment, StatefulSet, etc.) - remove it there first
  2. If pod has inherited-control-state annotation, removing from owner will automatically fix it
  3. If no inherited-control-state, the annotation was set directly on the pod - remove it manually from the pod

Interpreting Recommendation Annotations

Recommendation annotations use policy prefixes to indicate their source: Naming convention:
  • No prefix = namespace-scoped policy
  • cw prefix (cluster-wide) = cluster-scoped policy
  • The same fixed and hashed forms apply to desired-resource-limits annotations.
  • Consumers always read both forms. During a feature-flag transition, one workload may contain a mix while each policy converts its own annotations.
  • Treat exact annotation names as internal. Filter for rightsizing.kubex.ai/ plus desired-resource-requests or desired-resource-limits, then inspect policyKind, policyNamespace, and policyName in the JSON payload.
Example on a pod:

Multi-policy container rightsizing disabled

Multi-policy container rightsizing enabled

Interpretation: With multi-policy container rightsizing disabled, this ProactivePolicy uses fixed request and limit keys. When enabled, it uses policy-owned hashed keys for both. In either case, it recommends 500m CPU and 1Gi memory requests for the “app” container, plus a 1Gi memory limit. Missing annotations indicate that no policy matched the pod or recommendations haven’t been generated.

Interpreting Automation State Annotation

The rightsizing.kubex.ai/automation-constraints annotation appears only on pods and is the most important annotation for troubleshooting. It shows why automation is blocked or what filters are applied:

Annotation Format

The annotation is a JSON array where each entry represents a constraint with a reason code and a targets array specifying what is affected: Structure:
Understanding targets:
  • Empty array [] = Global constraint affecting the entire pod
  • Non-empty array = Constraint applies only to the specific container/resource/usage combinations listed
Common reason codes include:
  • hpa-resource-managed
  • namespace-protected
  • pause-active
  • limit-range-violated
  • resource-quota-exceeded
  • automation-strategy-disabled
  • scheduling-window-blocked
  • ephemeral-storage-restart-pending
Example - HPA managing specific resources:
What this means: HPA is managing CPU requests and limits for the “app” container. Memory automation is unaffected since it’s not in the targets list. Example - Pause active:
What this means: Automation is paused for this pod. Empty targets indicates this blocks all automation. Check for pause-until annotation on the pod, pod owner, or namespace.

Interpreting Rollback State (Pod Owner Only)

The rollback-state annotation appears only on pod owners and tracks rollback progress:
Key fields: Example:
Interpretation: Rollback triggered due to excessive pod restarts. Currently in backoff period. Automation will resume after expiry time. For more details on rollback behavior, see Rollback Documentation.

1. Interpret Rightsizing Summary Logs

The controller logs a rightsizing summary for each evaluation. These logs are your primary diagnostic tool.

Key Log Fields

Note: The log format includes internal details like INFO/BLOCKER distinctions and full metadata. The automation-constraints annotation on pods uses a simplified format for easier troubleshooting. See Interpreting Automation State Annotation for the annotation structure.

Common Outcomes

Example Log Analysis

Example 1: Blocked by pause annotation
Action: Check pod, pod owner, and namespace for rightsizing.kubex.ai/pause-until annotation. Example 2: Container filtered out
Action: Check rightsizing.kubex.ai/skip-containers annotation. One container was skipped, but others were resized successfully. Example 3: Temporarily blocked
Action: Wait. Controller will retry automatically when pod becomes ready. This is normal during rollouts.

2. Check Global Health

The GlobalConfiguration resource controls cluster-wide automation behavior. Start here to rule out global issues.
Expected output sections:
  • spec.automationEnabled: true - Global automation switch
  • status.conditions - Should show Ready conditions
  • spec.protectedNamespacePatterns - List of protected namespaces

What to Check

Common Issues

Automation globally disabled
Fix: Set automationEnabled: true Namespace is protected
Fix: Remove the pattern or rename your namespace GlobalConfiguration not Ready How to spot:
  • Run kubectl get globalconfiguration global-config and look at the READY column. If it shows False or is missing, there’s an issue.
  • Controller logs will show error messages like:
    • "pod admission webhook probe failed" (webhook health issues)
    • "failed to reload recommendations" (recommendation sync failures)
    • Events will be emitted: PodAdmissionWebhookUnhealthy, RecommendationReloadFailed, or ProposalReloadFailed
This happens when the controller detects a critical issue preventing safe operation. Common causes:
  • Webhook health check failing: Probe pod cannot be created (often due to image policies). New pods won’t get recommendations applied.
  • Recommendation sync failing: Cannot connect to Kubex platform API. Proactive policies won’t have fresh recommendations.
  • Controller not running: Pod crashed or failed to start.
Action: Check status.conditions in GlobalConfiguration to identify which component failed, then check controller logs for details. If webhook health is failing, see Webhook and System Blockers.

Important Notes

  • Webhook failures usually appear as missed mutations, not rejected pod admissions. New pods will be created but won’t have recommendations applied.
  • If webhook health becomes unhealthy, proactive automation may pause until probe health recovers. This is a safety mechanism.
  • Validating webhook rejection behavior depends on webhook.failurePolicy (defaults to Ignore), so failed webhook calls won’t block pod creation.
  • If POD_NAMESPACE environment variable is missing in a custom deployment, the controller will fail to start. This is rare unless you’ve modified the Helm chart.

3. Check Policy and Strategy Resolution

Policies (ProactivePolicy, StaticPolicy, etc.) define what to resize. AutomationStrategies define how to resize (in-place vs eviction, safety checks, etc.). If your policy references a strategy that doesn’t exist or is invalid, automation won’t work.

Check Policies

Check Strategies

What to Look For

Status fields:
  • resolvedStrategy - Should show the strategy name if found
  • conditions - Look for errors like StrategyNotFound or InvalidReference
Events:
  • StrategyResolved - Good! Strategy was found and is valid
  • StrategyNotFound - Problem: Referenced strategy doesn’t exist
  • InvalidStrategyReference - Problem: Strategy reference is malformed

Common Issues

Strategy not found
Fix: Create the strategy or update the policy to reference an existing strategy. Invalid strategy reference
Fix: Provide a valid strategy name. Namespace vs Cluster scope mismatch
  • ProactivePolicy (namespace-scoped) can reference AutomationStrategy (namespace) or ClusterAutomationStrategy (cluster)
  • ClusterProactivePolicy (cluster-scoped) can only reference ClusterAutomationStrategy (cluster)

4. Check Runtime Events

Kubernetes events provide a timeline of what the controller has done. Use these to see policy evaluation outcomes and identify patterns.

Useful Event Queries

Interpreting Events

Example: Finding Why Automation Is Blocked

Output:
This tells you the pod is blocked by a pause annotation. Check the pod and its owner for rightsizing.kubex.ai/pause-until.

5. Common Blockers

Use the steps above to identify blockers, then consult this list for common causes and solutions. Blockers are grouped by frequency and impact. Quick annotation lookup:

Resource Conflict Blockers (Critical - Requires Immediate Action)

Workload Availability Blockers (Temporary - Usually Auto-Resolves)

Webhook and System Blockers (Configuration Issues)

Workload-Specific Blockers (Rare)

6. Verify Webhook Registration

The mutating admission webhook intercepts pod creation and applies resource recommendations. If the webhook isn’t registered properly, new pods won’t get recommendations applied.

Check Webhook Configuration

Expected output: You should see a webhook configuration with a name like kubex-automation-engine-mutating-webhook-configuration.

Verify Webhook Details

What to check:
  • Rules - Should match pods in your target namespaces
  • Failure Policy - Usually Ignore (fail-open) to prevent blocking pod creation if webhook is down
  • Service - Should point to the controller service
  • CA Bundle - Should be present (base64-encoded certificate)

Common Issues

Webhook not found
Fix: The webhook may not have been created during installation. Check Helm values and reinstall if necessary. Webhook not being called
  • Check namespace labels: Some webhooks use namespaceSelector to filter which namespaces they apply to
  • Check object selector: Webhook may filter based on pod labels or annotations
  • Check failure policy: If set to Fail, webhook failures will block pod creation (rare)
Webhook failing but pods still created
  • This is expected behavior with failurePolicy: Ignore (fail-open)
  • Pods are created, but recommendations aren’t applied
  • Check webhook health in GlobalConfiguration (step 2)
  • Check controller logs for webhook errors

Additional Resources

For advanced webhook tuning in slow or degraded environments, see Tuning Guide.

Quick Diagnostic Commands

View Automation State and Blockers

Check Control Annotations

Check Rollback State (Pod Owners)

Collect Support Information

If automation still isn’t working after following all troubleshooting steps, collect this information:
For performance tuning and optimization, see Tuning Guide.

Enable Debug Logging (Rarely Needed)

⚠️ Debug logging is rarely needed. The controller provides extensive troubleshooting information via annotations (automation-constraints, rollback-state), events (PrecheckFailed, policy evaluation outcomes), and info-level summary logs. Only enable debug logging when:
  • Investigating controller internal behavior not visible in annotations or events
  • Troubleshooting controller crashes or performance issues
  • Requested by Kubex support for deep diagnostics
Always start with annotations, summary logs, and events before enabling debug logging.
Most of the time you only want debug logs briefly. The quickest way is to update the live Deployment args (this triggers a rollout and will be overwritten by the next helm upgrade). Enable debug (temporary):
Revert back to info:
If you want the setting to persist across upgrades, use Helm instead: Enable debug (persistent):
Revert with Helm: