kubectl, helm, and gcloud calls used throughout this page, skip to Diagnostic commands.
Automated diagnostics
Before running individual commands, try the bundled scripts:Known issues
terraform apply fails: GCP APIs not enabled
Symptomgoogle_project_service, but cloudresourcemanager.googleapis.com must already be enabled for Terraform to enable the others.
Fix
GKE cluster API server not accessible after apply
SymptomRUNNING then adds a 90-second buffer. Cold-start API activation on slow projects can exceed the window.
Fix: Wait for RUNNING, then re-run:
GKE nodes not joining (NotReady)
Symptom:kubectl get nodes shows no nodes or nodes stuck in NotReady.
Cause: Node pool service account lacks roles/container.nodeServiceAccount, or VPC firewall rules block node-to-control-plane communication.
Fix
Cloud SQL connection refused from GKE pods
Symptom: Backend logs showconnection refused or no route to host for the Cloud SQL private IP.
Cause: The private service connection (VPC peering) is not established, or the allocated IP range is too small. Often happens when servicenetworking.googleapis.com was not enabled before the networking module ran.
Fix
postgres_source = "external", redis_source = "external", enable_sandboxes = true, or SmithDB creates its own metastore. If peering is missing, confirm one of those settings is in terraform.tfvars and re-apply:
Memorystore Redis connection timeout
Symptom: Pods cannot connect to Redis. Logs showdial tcp: connection timed out or redis: connection refused.
Cause: The Memorystore authorized_network does not match the GKE VPC, or the Redis private IP is on a range not routable from the GKE subnet.
Fix
cert-manager fails to issue Let’s Encrypt certificate
Symptom:kubectl get certificate -n langsmith shows READY=False. HTTP01 challenge failing.
Cause: The DNS A record does not point to the Envoy Gateway IP, or port 80 is blocked on the load balancer.
Fix
GCS bucket access denied from LangSmith pods
Symptom: Backend logs showAccessDeniedException: 403 Insufficient Permission or 403 Forbidden when writing to GCS.
Cause: In native GCS mode (the shipped default), the GCP service account bound through Workload Identity lacks roles/storage.objectAdmin on the bucket, or the pod’s Kubernetes ServiceAccount is missing the iam.gke.io/gcp-service-account annotation. In the optional S3-compatible mode, the HMAC credentials passed to Helm are incorrect or their service account lacks roles/storage.objectAdmin.
Fix
roles/storage.objectAdmin on the bucket. If the annotation itself is missing, apply the fix in the Workload Identity section below. For S3-compatible mode, create an HMAC key under Cloud Storage > Settings > Interoperability; its service account also needs roles/storage.objectAdmin on the bucket.
Envoy Gateway webhook blocking GKE operations
SymptomcaBundle is stale.
Fix
Envoy Gateway external IP changed after re-apply
Symptom: DNS no longer resolves to the correct IP after Terraform re-apply, or existing firewall allowlists stop working. Cause: The Envoy Gateway external IP is tied to theGateway Kubernetes resource managed by Terraform. If the resource is deleted and recreated (terraform taint, a module change that forces replacement, or terraform destroy + re-apply), GCP issues a new IP. There is no way to reserve the original IP without pre-allocating a static regional address.
Prevention
- Do not
terraform taintor manually delete theGatewayresource. - Use
make destroy+make applyonly for full teardown and rebuild. - Before any operation that might recreate the Gateway, note the current IP.
terraform destroy fails: deletion protection enabled
Symptomgke_deletion_protection, postgres_deletion_protection, or smithdb_metastore_deletion_protection is true. Cloud SQL enforces deletion protection at the API level as well as in Terraform, so changing terraform.tfvars has no effect until the change is applied.
Fix
module.smithdb target if you never enabled SmithDB. The targeted apply avoids reconciling the in-cluster add-ons that a full make apply would recreate.
Workload Identity not working (GCS permission denied)
Symptomlangsmith-ksa missing Workload Identity annotation
Symptom: Operator-spawned agent pods fail to start or get stuck in Pending. Logs show permission errors.
Cause: Terraform creates langsmith-ksa in the k8s-bootstrap module and annotates it only when enable_gcp_iam_module = true. deploy.sh re-applies the annotation after each deploy. The annotation is missing if the IAM module is off, the namespace was deleted out-of-band, or a previous deploy was interrupted.
Diagnosis
enable_gcp_iam_module = false, set it to true in terraform.tfvars and run make apply. For the other causes, re-run the deploy or annotate the ServiceAccount manually:
Deploy refuses chart 0.16 sandbox values
Symptomvalues-overrides.yaml was generated for chart 0.16. Chart 0.17 has no JuiceFS CSI driver and ignores the sandboxes.juicefs.csi block.
Fix: Run make apply, then make init-values to regenerate the file, then make deploy.
Deploy refuses while JuiceFS CSI volumes remain
SymptomTerminating.
Fix: Run the kubectl delete commands that the error prints while the driver still runs. Wait until kubectl get pods -n langsmith | grep juicefs lists only juicefs-csi-* pods, then run make deploy again. Running sandboxes stop. Their data stays in object storage and Redis, and chart 0.17 mounts the same JuiceFS volume.
Deploy refuses the chart 0.16 SmithDB overlay
Symptominit-values.sh copies the SmithDB overlay only once, so a chart 0.16 copy stays in helm/values/. It sets the local-ssd-storage volume or smithdb.migration.deployment, which chart 0.17 replaces.
Fix: Save your copy and start from the 0.17 example:
nodeSelector, tolerations, volumes, volumeMounts, or resources. The generated langsmith-values-smithdb-sizing.yaml now sets those.
init-values.sh fails with missing SmithDB outputs
Symptom
make apply, then make init-values.
Deploy refuses because the SmithDB backfill Job changed
Symptommake deploy again. The backfill keeps its progress in the task database, so the new Job resumes instead of starting over.
JuiceFS format Job fails
Symptomjuicefs-format Job formats the sandbox volume in the GCS bucket through the langsmith-sandbox-host Workload Identity binding. When the reason is DeadlineExceeded, the Job did not finish within 300 seconds, usually because the pod could not schedule or the image pull was slow. For any other reason, the binding is usually missing or out of date.
Fix:
-
Find the cause. For
DeadlineExceeded, look forFailedSchedulingevents or a slow image pull:For any other reason, read the Job logs, then runmake applyto restore the Workload Identity binding: -
Delete the failed Job and deploy again. Helm does not rerun a failed Job when its manifest is unchanged, so the Job must be deleted first:
Helm release stuck in pending-upgrade
Symptom
helm upgrade was interrupted (Ctrl+C during --wait). Helm left the release locked.
Fix: deploy.sh detects and auto-recovers this state. If running manually:
Secret Manager access denied
Symptomsecretmanager.googleapis.com is not enabled, or the operator account lacks roles/secretmanager.admin.
Fix
main or a v0.17.x tag, because the project-wide roles/secretmanager.secretAccessor grant is now opt-in. Grant access on the specific secrets, or set grant_project_secret_accessor = true and run make apply.
langsmith-postgres-credentials or langsmith-redis-credentials Secret missing
Symptom: Pods crash with database connection errors immediately after deploy, or kubectl get secrets -n langsmith does not list langsmith-postgres-credentials / langsmith-redis-credentials.
Cause: The k8s-bootstrap module creates these Secrets when postgres_source or redis_source is external. They are absent if terraform apply was not run, failed partway through, or the namespace was deleted out-of-band.
Fix
Diagnostic commands
Cluster access
Pods
TLS and certificates
Gateway and load balancer
Helm
LangSmith Deployment
Workload Identity and IAM
Secrets and bootstrap
Quick health check
Connect these docs to your agent of choice via MCP for real-time answers.

