4. Verify deployment
Owner: Cloud Ops
Run the common checks for every installation, then complete the ingress and database checks for the selected cloud. Do not hand the endpoint to IT until it works from a network representative of managed devices.
Record the deployment identity
Section titled “Record the deployment identity”Before troubleshooting, write down:
- Cloud provider, account/project/subscription, and region.
- Terraform release tag and Helm chart version.
- Kubernetes cluster name and namespace.
- Customer HTTPS hostname.
- Whether GPU embedding, SCIM, and the Admin UI are enabled.
This prevents commands from being run against the wrong customer environment.
Runtime and secret health
Section titled “Runtime and secret health”kubectl get pods,svc,ingress,cronjob -n arbiumkubectl get externalsecret -n arbiumkubectl get events -n arbium --sort-by='.lastTimestamp' | tail -30Expected application pods:
chaindb-edge-fns: ready replicas matching the configured baseline.embedder: one ready CPU or GPU pod.chaindb-scim: ready only whenscim.enabled=true.admin-ui: ready only whenadmin.enabled=true.
Expected scheduler CronJobs include close-stale-sessions, drain-batch, and
nightly-enqueue.
Every required ExternalSecret should report a successful sync. Confirm the runtime and pull Secrets exist without printing their values:
kubectl get secret chaindb-runtime ghcr-pull -n arbiumkubectl describe externalsecret -n arbiumIf the Admin UI or SCIM is enabled, also expect admin-ui-oidc,
admin-ui-session, and scim-bearer as configured.
Provider ingress and TLS
Section titled “Provider ingress and TLS”kubectl get ingress chaindb -n arbiumkubectl describe ingress chaindb -n arbiumThe Ingress address should be an AWS ALB hostname. The customer DNS record must
point to that hostname, and the attached ACM certificate must be ISSUED in the
same region as the ALB.
Google Cloud
Section titled “Google Cloud”kubectl get ingress chaindb -n arbiumkubectl get managedcertificate chaindb-tls -n arbiumkubectl describe managedcertificate chaindb-tls -n arbiumThe Ingress address should match the Terraform static IP and DNS A record. Wait
for the managed certificate to become Active; provisioning commonly takes
10–60 minutes after DNS resolves.
kubectl get ingress chaindb -n arbiumkubectl get certificate chaindb-tls -n arbiumkubectl describe certificate chaindb-tls -n arbiumThe Ingress address should match the Terraform static IP and DNS A record. The
certificate should report Ready=True and the chaindb-tls Secret should
exist.
In-cluster health
Section titled “In-cluster health”kubectl run chaindb-health-check \ -n arbium \ --rm -i \ --restart=Never \ --image=curlimages/curl:8.11.1 \ -- -fsS http://chaindb-edge-fns:8000/functions/v1/healthExpected response:
{ "ok": true }A timestamp field may also be present.
External endpoint health
Section titled “External endpoint health”From a representative managed-device network:
curl -fsS https://arbium.<customer-domain>/functions/v1/healthcurl -fsS https://arbium.<customer-domain>/functions/v1/auth-config/health proves the application is reachable through the provider ingress and
TLS. /auth-config proves clients can discover the configured Entra method.
Confirm the backend received the intended OIDC values:
kubectl -n arbium get configmap chaindb-config \ -o jsonpath='{.data.OIDC_ISSUER_URL}{"\n"}{.data.OIDC_AUDIENCE}{"\n"}{.data.OIDC_ALLOWED_ALGS}{"\n"}'Expected: the customer’s v2 Entra issuer URL, the bare Arbium Agent client GUID,
and RS256.
SCIM endpoint
Section titled “SCIM endpoint”Skip this section when scim.enabled=false.
Use the deployed SCIM token from the approved secret channel:
BASE=https://arbium.<customer-domain>/scim/v2SCIM_TOKEN=<deployed-scim-token>
curl -i "$BASE/ServiceProviderConfig" \ -H "authorization: Bearer $SCIM_TOKEN"
curl -i "$BASE/Schemas" \ -H "authorization: Bearer $SCIM_TOKEN"Expected: HTTP 200 with application/scim+json. An incorrect token should
return 401, not redirect to Microsoft sign-in.
Admin UI
Section titled “Admin UI”Skip this section when admin.enabled=false.
kubectl get pod -n arbium -l app.kubernetes.io/component=admin-uikubectl logs -n arbium deploy/admin-ui --tail=50curl -fsSI https://arbium.<customer-domain>/admin/api/healthzThe health endpoint should return 200. IT completes the signed-in browser
test because it requires a provisioned user in the customer tenant.
Troubleshooting
Section titled “Troubleshooting”External Secrets are not ready
Section titled “External Secrets are not ready”kubectl describe clustersecretstore chaindb-secret-storekubectl describe externalsecret -n arbiumkubectl logs -n external-secrets deploy/external-secrets --tail=200Check the provider-specific identity:
- AWS: the
esoservice account IRSA annotation and IAM permission on the exact Secrets Manager ARNs. - Google Cloud: the GSA annotation, Workload Identity binding, project ID, cluster name, and region.
- Azure: the managed-identity client ID, tenant ID, Key Vault URI, federated
credential, and
Key Vault Secrets Userrole.
Pods report ImagePullBackOff
Section titled “Pods report ImagePullBackOff”kubectl get secret ghcr-pull -n arbiumkubectl describe pod -n arbium <pod-name>Confirm the cloud registry secret contains valid JSON with username and
token, the token has read:packages, and the provider overlay enables
externalSecrets.imagePullSecret with target name ghcr-pull.
Edge functions fail during migrations or startup
Section titled “Edge functions fail during migrations or startup”kubectl logs -n arbium deploy/chaindb-edge-fns -c migrations --tail=200kubectl logs -n arbium deploy/chaindb-edge-fns -c edge-fns --tail=200Check the database path for the selected provider:
| Provider | Expected connection | Common failure |
|---|---|---|
| AWS | Direct Aurora endpoint with sslmode=require |
Security group, stale/unauthorized RDS secret, or wrong endpoint |
| Google Cloud | arbium-cloud-sql-proxy Service with application SSL disabled |
Proxy Workload Identity, connection name, or incorrectly encoded password |
| Azure | Private Flexible Server endpoint with sslmode=require |
Private DNS/VNet connectivity, Key Vault sync, or TLS configuration |
Migrations are idempotent. Do not disable migrations.runOnStartup to hide a
database error; fix the underlying connection or migration failure.
Embedder is pending or restarting
Section titled “Embedder is pending or restarting”kubectl describe pod -n arbium -l app.kubernetes.io/component=embedderkubectl top nodes- In CPU mode, increase general-node capacity or the node-pool maximum.
- In GPU mode, confirm a node advertises
nvidia.com/gpu, matches the cloud preset’s selector, and has the expected taints and tolerations. - Azure CPU mode is the baseline unless an AKS GPU pool was added explicitly.
Ingress has no address or HTTPS fails
Section titled “Ingress has no address or HTTPS fails”Start with kubectl describe ingress chaindb -n arbium, then inspect the
provider controller:
# AWSkubectl logs -n kube-system deployment/aws-load-balancer-controller --tail=200
# Azurekubectl logs -n ingress-nginx deployment/ingress-nginx-controller --tail=200kubectl logs -n cert-manager deployment/cert-manager --tail=200For Google Cloud, inspect the Ingress events, static IP annotation, DNS A record, and ManagedCertificate domain status. For every provider, verify the certificate covers the exact configured hostname.
Admin UI pod fails or sign-in redirects loop
Section titled “Admin UI pod fails or sign-in redirects loop”kubectl logs -n arbium deploy/admin-ui --tail=200AADSTS50011: the Entra Web redirect URI must exactly matchhttps://<host>/admin/api/auth/callback.consent_required: grant tenant admin consent for every delegated permission on the Arbium Admin application.invalid_client: rotate the Entra client secret, update the cloud secret store, wait for External Secrets to sync, and restartadmin-ui./forbidden: verify the user, admin group, and group membership were synced through SCIM and thatscim.scimAdminGroupIdscontains Entra group object IDs.
Scheduler CronJobs fail
Section titled “Scheduler CronJobs fail”kubectl logs -n arbium -l app.kubernetes.io/component=scheduler --tail=100Confirm the scheduler token synced into chaindb-runtime and that the in-cluster
edge-functions Service is reachable. Suspend the CronJobs while debugging and
resume them after health checks pass.
Continue to 5. Handoff to IT.