Skip to main content
Every installer failure prints two lines: FIX:, the action that repairs the condition, and RERUN:, your personalized non-interactive one-liner (secrets typed at prompts are shown as placeholders). The installer is idempotent: fix the condition, paste the rerun line, and it picks up where the failure left off. A secret-scrubbed session log is kept under ~/.xpander/logs/ (latest.log points at the most recent run). For scripted runs, the exit code names the failure class (Automation and CI), and bash install.sh status gives a read-only health verdict.

Installer

install.sh upgrade requires the release to be in deployed status. Operating on a stuck release (pending-install, pending-upgrade, pending-rollback, failed, uninstalling) would strand it. Recover first:
Then paste your RERUN: line. A pending-install status usually means a first install was interrupted (Ctrl-C, lost connection) or timed out: helm uninstall is the right recovery for it.
The two self-hosted deployments share nothing and cannot be upgraded into each other. If the release name in the namespace already runs the other chart, the installer stops with the collision. Install under a different release or namespace (--release / --namespace), or remove the existing release first (helm uninstall xpander -n xpander).
Piping the installer into bash leaves no stdin to prompt on, so a piped run is non-interactive (the same contract as --non-interactive). Hybrid requires --org, --env, and --dm-api-key. Missing flags exit with code 2 and a completed rerun line. Copy the personalized one-liner from the xpander console, it carries the identity flags, or download the script and run bash install.sh for the interactive wizard.

Cluster and pods

The init containers wait for agent-controller to be ready. Check its logs:
Common cause: Cannot reach the deployment manager. If using PrivateLink, verify the DNS and security groups are configured correctly: see PrivateLink.
Cause: Storage class or PVC issues.
Check that a default StorageClass exists and the EBS CSI driver is running:
If using EKS, ensure the node role has AmazonEBSCSIDriverPolicy attached.
You are running on ARM/Graviton nodes. xpander images are amd64 only. Switch to x86 instance types (t3, m5, c5, etc.).
The agent-worker pod requests 2 CPU by default. Two options:
  • Add more nodes, or use larger instances.
  • For non-production environments only, lower the CPU request directly on the xpander-agent-worker Deployment in the xpander namespace:
Check application logs (skill calls, including AWS ones, log in agent-controller):

Ingress and networking

Verify ingress configuration:
Check that the NLB was provisioned and DNS CNAME records point to it:
Symptom: the ingress controller’s Service stays <pending>. Check its events (kubectl -n ingress-nginx describe svc ingress-nginx-controller):
  • could not find any suitable subnets for creating the ELB: the VPC’s subnets are missing the ELB role tags. Tag public subnets kubernetes.io/role/elb=1 for an internet-facing NLB. For an internal one, tag the private subnets kubernetes.io/role/internal-elb=1 and annotate the Service service.beta.kubernetes.io/aws-load-balancer-internal: "true".
  • On EKS Auto Mode, ensure the cluster role trust policy includes sts:TagSession:
The ACM certificate must include *.chat.<DOMAIN> as a subject alternative name. The chat UI generates per-thread subdomains (e.g., moccasin-prawn.chat.<DOMAIN>) that are not covered by *.<DOMAIN>.Request a new certificate with:

API keys

The xpander-static secret has a Helm resource keep policy, so a helm upgrade does not update it on its own. Patch the key directly on the xpander-static Kubernetes secret in the xpander namespace:
See the secret field name mapping for all key names.
New agent runs wait for a healthy LLM Gateway. Check its pods and the reason they are not ready (an image the cluster cannot pull is the usual one):
See LLM Gateway for the healthy result.If you mirror images, mirror xpanderaihub/llm-gw and point images.llmGw or global.imageRegistry at it. The gateway cannot be turned off, so new runs wait until its pods are ready.
A call to a provider with no key, neither in the organization (Platform > AI governance > Models) nor on the install (secrets.static), is refused with a message that names the missing key. Add the key in either place. To check the install’s keys, verify they reach the agent-worker pod:
If missing, re-run the upgrade with the key set (--set secrets.static.<key>=...), or check that your secret is correctly mounted through envFromSecretKeys: see Model keys and Bedrock.

Debug commands