Troubleshooting
Database Connection Failed
# Check database is running
docker compose ps db
# Test connection
docker compose exec db psql -U postgres -c "SELECT 1"Verify DATABASE_URL format: postgresql://user:pass@host:5432/database
Ollama Models Not Showing
Inside Docker, localhost = the container, not your host machine.
# For host-machine Ollama, use:
OLLAMA_URL=http://host.docker.internal:11434 # macOS/Windows
OLLAMA_URL=http://192.168.1.x:11434 # Linux (use actual IP)WebSocket/Realtime Not Working
- Verify reverse proxy routes
/socket.ioto the realtime service (default port 3002).NEXT_PUBLIC_SOCKET_URLis only needed if realtime is on a separate host. - Verify realtime service is running:
docker compose ps realtime - Ensure reverse proxy passes WebSocket upgrades (see Docker guide)
502 Bad Gateway
# Check app is running
docker compose ps simstudio
docker compose logs simstudio
# Common causes: out of memory, database not readyMigration Errors
Migrations run in their own migrations service and image — the app image does not contain the migration tooling.
# View migration logs
docker compose -f docker-compose.prod.yml logs migrations
# Re-run them
docker compose -f docker-compose.prod.yml up --force-recreate migrationsOn Kubernetes, migrations are an init container on the app pod:
kubectl logs -n simstudio deploy/sim-app -c migrations --tail=200pgvector Not Found
Use the correct PostgreSQL image:
image: pgvector/pgvector:pg17 # NOT postgres:17Certificate Errors (CERT_HAS_EXPIRED)
If you see SSL certificate errors when calling external APIs:
The image already ships current CA certificates and runs as a non-root user, so installing packages inside it is not the fix. This almost always means the endpoint presents a certificate signed by a private CA — a corporate TLS-inspecting proxy, or an internal service.
Mount your CA bundle and point Node at it:
# docker-compose.prod.yml
services:
simstudio:
volumes:
- /etc/ssl/certs/corporate-ca.crt:/certs/corporate-ca.crt:ro
environment:
- NODE_EXTRA_CA_CERTS=/certs/corporate-ca.crt# Helm — mount a ConfigMap holding the CA
app:
env:
NODE_EXTRA_CA_CERTS: /certs/corporate-ca.crt
extraVolumes:
- name: corporate-ca
configMap:
name: corporate-ca
extraVolumeMounts:
- name: corporate-ca
mountPath: /certs
readOnly: trueNODE_TLS_REJECT_UNAUTHORIZED=0 disables certificate verification entirely and should never be used outside a throwaway test.
Blank Page After Login
- Check browser console for errors
- Verify
NEXT_PUBLIC_APP_URLmatches your actual domain - Clear browser cookies and local storage
- Check that all services are running:
docker compose ps
Windows-Specific Issues
These apply to running Sim from source for development, not to the Docker or Kubernetes deployments, which are unaffected by the host OS.
Turbopack errors on Windows: use WSL2.
wsl --installLine ending issues:
# Configure git to use LF
git config --global core.autocrlf inputView Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f simstudioScheduled Workflows Never Run
The most common self-hosting surprise.
Docker Compose — check the cron service is running and read its logs:
docker compose -f docker-compose.prod.yml logs --tail=50 cronA 401 there means the app and the scheduler disagree on CRON_SECRET.
Kubernetes — check the CronJobs are present and firing:
kubectl get cronjobs -n simstudio
kubectl get jobs -n simstudio --sort-by=.metadata.creationTimestamp | tailA stale LAST SCHEDULE or failing jobs usually means CRON_SECRET is missing or does not match between the cron pods and the app. Call the endpoint by hand to see the status code:
kubectl exec -n simstudio deploy/sim-app -- sh -c \
'curl -s -o /dev/null -w "%{http_code}\n" \
-H "Authorization: Bearer $CRON_SECRET" \
http://localhost:3000/api/schedules/execute'Wrap it in sh -c with single quotes so $CRON_SECRET expands inside the pod — otherwise your local shell substitutes an empty value and you get a misleading 401.
401 means the secret does not match. 202 means the endpoint accepted the run; it does not tell you whether a schedule was actually due, so confirm in the Logs view.
Gmail / Drive / Outlook Triggers Never Fire
These are polling triggers, driven by the per-minute /api/webhooks/poll/* jobs. Check the scheduler is running them — docker compose logs cron, or kubectl get cronjobs -n simstudio for a recent LAST SCHEDULE.
Microsoft Teams chat triggers are the different case: they use a Microsoft Graph subscription capped at about three days, renewed by the twice-daily renew-subscriptions job. If Teams triggers work for a couple of days and then stop, that job is not running. See Background Jobs.
Collaboration Breaks With Multiple Replicas
Two users editing the same workflow stop seeing each other, or live status never updates — with no error anywhere.
This is Redis. Pub/sub and the Socket.IO adapter have no cross-pod fallback:
kubectl exec -n simstudio deploy/sim-app -- printenv REDIS_URL
kubectl exec -n simstudio deploy/sim-realtime -- printenv REDIS_URLBoth pods must have REDIS_URL. On Helm they share one Secret, so setting it under app.env covers both. See Redis.
App Crashes at Startup With a REDIS_TLS_SERVERNAME Error
REDIS_URL uses rediss:// pointed at a bare IP address. TLS certificates cannot be verified against an IP, so set REDIS_TLS_SERVERNAME to the DNS name the certificate was issued for — or use a DNS hostname in the URL instead.
File Uploads Fail With a CORS Error
The bucket's CORS policy does not allow your Sim origin. Uploads go directly from the browser to object storage via presigned PUT, so server-side configuration being correct is not enough.
If small uploads succeed but files over 50 MB fail during completion, check the app logs for the provider's part-listing request. The server completes multipart uploads from provider-authoritative state; for S3, its identity needs s3:ListMultipartUploadParts. See Object Storage.
Agent Output Arrives All at Once
Your reverse proxy is buffering the response stream. Set proxy_buffering off (Nginx) or flush_interval -1 (Caddy). See Networking.
Websockets Disconnect Every 30 Seconds
The load balancer's backend timeout is closing them. On GKE, attach a BackendConfig with timeoutSec: 3600 to the realtime Service; on AWS, raise the ALB idle_timeout. Clients reconnect, so this degrades rather than breaks. See Networking.
Knowledge Base Upload Fails
Embeddings need a hosted provider — set OPENAI_API_KEY, configure Azure OpenAI, or set KB_EMBEDDING_MODEL=gemini-embedding-001 with a Gemini key. There is no local embedding backend, so Ollama or vLLM does not substitute. If a key is set, verify pgvector is installed on the database.
Credentials Unreadable After a Restore
Integrations show as connected but fail, or provider keys error on decrypt. ENCRYPTION_KEY does not match the value in use when the backup was taken. There is no recovery — the original key must be restored.
Kubernetes: App Pods Never Become Ready
Check the migrations init container first — a failed migration deliberately blocks the rollout:
kubectl logs -n simstudio deploy/sim-app -c migrations --tail=200
kubectl describe pod -n simstudio <pod>Common causes: DATABASE_URL unreachable, the database user lacking rights to create the vector extension, or an OOMKill from insufficient memory. See Upgrades for migration-failure recovery.
Kubernetes: ImagePullBackOff
Either the tag does not exist in the registry (helm get values sim and check), or you are pulling from a private registry without global.imagePullSecrets. When mirroring into a private registry, set global.useRegistryForAllImages: true — otherwise third-party images still point at Docker Hub.
Kubernetes: Postgres Pod Pending
kubectl describe pvc -n simstudioAlmost always no default StorageClass, no PV provisioner installed, or a StorageClass that does not support ReadWriteOnce. Set global.storageClass to pick a specific one.