self-hosting
Troubleshooting

Troubleshooting

Common issues and fixes for self-hosted Orsa instances.

Browser Pool Won't Start

Symptoms

  • Browser worker container exits immediately
  • Health check at /health returns connection refused
  • Logs show Failed to launch browser or Chromium not found

Fixes

Shared memory too small:

# Docker Compose — add shm_size
services:
  browser-worker:
    shm_size: '512mb'  # Must be ≥256 MB
 
# Kubernetes — mount emptyDir as /dev/shm
volumes:
  - name: dshm
    emptyDir:
      medium: Memory
      sizeLimit: 512Mi

Missing Chromium dependencies (non-Docker):

# Debian/Ubuntu
apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 \
  libcups2 libdrm2 libdbus-1-3 libxkbcommon0 libatspi2.0-0 \
  libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 \
  libpango-1.0-0 libcairo2 libasound2 fonts-liberation
 
# Or install all Playwright deps automatically
npx playwright install-deps chromium

Playwright browsers not installed:

npx playwright install chromium

Not enough memory: Each Chromium instance needs ~200-400 MB RAM. If BROWSER_POOL_SIZE=3, ensure at least 2 GB available.

# Check container memory
docker stats orsa-browser-worker-1

Port conflict:

# Check if port 3002 is in use
lsof -i :3002
 
# Change the port
docker compose up -d  # Uses PORT from environment

Proxy Errors

Symptoms

  • 407 Proxy Authentication Required
  • ECONNREFUSED to proxy host
  • Scraping returns blocked/CAPTCHA pages
  • ProxyError: tunnel connection failed

Fixes

Authentication failure (407):

# Verify proxy URL format — must include credentials
PROXY_DATACENTER_URL=http://USERNAME:PASSWORD@proxy-host:port
 
# Special characters in password? URL-encode them
# @ → %40, : → %3A, # → %23
PROXY_DATACENTER_URL=http://user:p%40ssw%23rd@proxy-host:port

Proxy connection refused:

# Test proxy directly
curl -x "http://user:pass@proxy-host:port" https://httpbin.org/ip
 
# Check if proxy provider IP allowlist is configured
# Many providers require you to whitelist your server's IP

Getting blocked despite proxies:

  • Upgrade proxy tier (datacenter → residential → ISP)
  • Check if the target site requires JavaScript rendering (use the browser worker instead of direct HTTP)
  • Reduce request rate to the same domain
  • Enable proxy rotation (most providers support this natively)

Disable proxy escalation for debugging:

PROXY_ESCALATION_ENABLED=false

Database Connection Issues

Symptoms

  • ECONNREFUSED to Supabase URL
  • JWT expired or Invalid API key
  • relation "brands" does not exist
  • Timeout connecting to database

Fixes

Wrong Supabase URL:

# Local development
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321  # Not 54323 (that's Studio)
 
# Cloud
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co  # No trailing slash

Migrations not applied:

# Check migration status
supabase migration list
 
# Apply pending migrations
supabase db push
 
# Nuclear option — reset and reapply everything
supabase db reset  # WARNING: destroys all data

Supabase not running (local):

# Check status
supabase status
 
# Start/restart
supabase stop
supabase start

Service role key vs anon key confusion:

  • NEXT_PUBLIC_SUPABASE_ANON_KEY — Public key, used in browser, respects RLS
  • SUPABASE_SERVICE_ROLE_KEY — Server-side key, bypasses RLS. Never expose to client.

Connection pooling (production): If you're hitting connection limits, enable Supabase connection pooling:

# Use the pooled connection string (port 6543 instead of 5432)
# Supabase Dashboard → Settings → Database → Connection Pooling

Required extensions not enabled:

-- Run in Supabase SQL Editor or via migration
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE EXTENSION IF NOT EXISTS "vector";

Rate Limiting Not Working

Symptoms

  • All requests succeed regardless of plan limits
  • Rate limit headers missing from responses
  • @upstash/ratelimit errors in logs

Fixes

Redis not connected:

# Test Redis connection
curl "${UPSTASH_REDIS_REST_URL}/ping" \
  -H "Authorization: Bearer ${UPSTASH_REDIS_REST_TOKEN}"
# Must return {"result":"PONG"}

Wrong Redis URL format:

# Upstash REST API requires HTTPS URL, not redis:// protocol
# ✅ Correct
UPSTASH_REDIS_REST_URL=https://us1-xxxxx.upstash.io
 
# ❌ Wrong
UPSTASH_REDIS_REST_URL=redis://us1-xxxxx.upstash.io:6379

Self-hosted Redis without REST proxy:

The @upstash/redis SDK requires Upstash's REST API. If using self-hosted Redis, you need the REST proxy:

docker run -d --name redis-rest-proxy \
  -p 8079:8079 \
  -e REDIS_URL=redis://redis:6379 \
  ghcr.io/upstash/upstash-redis-rest-proxy:latest
 
UPSTASH_REDIS_REST_URL=http://localhost:8079
UPSTASH_REDIS_REST_TOKEN=your-proxy-token

Rate limit key not set:

Ensure API key authentication is working. Rate limits are keyed on the API key — if auth is bypassed, rate limiting won't bind to a specific user.


Cache Misses

Symptoms

  • Every request triggers a fresh extraction (slow responses)
  • cached: false in every response
  • Redis shows no keys with orsa:cache: prefix

Fixes

Redis not connected: Same as rate limiting — verify Redis connectivity first.

Cache TTL set to 0:

# Check your env — a TTL of 0 disables caching for that type
CACHE_TTL_BRAND=604800  # Should be > 0

Client bypassing cache: Check if clients are passing ?cache=false in their requests. This forces a fresh extraction.

Cache key mismatch: The cache key includes a hash of normalized parameters. If the domain normalization changed between versions, old cache entries won't match. Clear the cache:

# Clear all Orsa cache keys in Redis
# Via Upstash REST API:
curl -X POST "${UPSTASH_REDIS_REST_URL}/eval" \
  -H "Authorization: Bearer ${UPSTASH_REDIS_REST_TOKEN}" \
  -d '["local keys = redis.call(\"keys\", \"orsa:cache:*\"); for i,k in ipairs(keys) do redis.call(\"del\", k) end; return #keys", "0"]'

Redis memory full: If Redis runs out of memory, it evicts keys. Check memory usage:

curl "${UPSTASH_REDIS_REST_URL}/info/memory" \
  -H "Authorization: Bearer ${UPSTASH_REDIS_REST_TOKEN}"

Stripe Webhook Issues

Symptoms

  • Subscriptions created but credits not applied
  • Webhook signature verification failed in logs
  • Events not reaching your endpoint

Fixes

Wrong webhook secret:

# The webhook secret changes when you recreate the endpoint
# Local dev: stripe listen outputs the secret
stripe listen --forward-to localhost:3001/api/webhooks/stripe
# Look for: whsec_xxxxx
 
STRIPE_WEBHOOK_SECRET=whsec_xxxxx  # Must match exactly

Webhook URL not reachable:

  • Ensure your API is publicly accessible at the webhook URL
  • Check firewall rules
  • Verify the path: /api/webhooks/stripe (not /api/webhook/stripe)

Missing events: Make sure these events are enabled in the Stripe webhook configuration:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.paid
  • invoice.payment_failed

Build Failures

pnpm install fails

# Clear pnpm cache
pnpm store prune
 
# Delete node_modules and reinstall
rm -rf node_modules
find . -name "node_modules" -type d -prune -exec rm -rf {} +
pnpm install

TypeScript errors after update

# Regenerate database types
pnpm generate:types
 
# Clear Turbo cache
rm -rf .turbo
pnpm build

Docker build fails for browser worker

# Common: Docker buildx platform mismatch on M1/M2 Mac
docker build --platform linux/amd64 -t orsa-browser-worker ./services/browser-worker

Logs

Where to Find Logs

ComponentLocation
API (dev)Terminal running pnpm dev
API (Vercel)Vercel Dashboard → Logs
Browser Worker (Docker)docker compose logs browser-worker
Browser Worker (Fly.io)flyctl logs --app orsa-browser-pool
Supabase (local)supabase logs
Trigger.devTrigger.dev Dashboard → Runs

Enable Debug Logging

LOG_LEVEL=debug pnpm dev

Browser Worker Verbose Logs

# In docker-compose.yml or environment
LOG_LEVEL=debug
DEBUG=pw:browser*  # Playwright debug logs

Getting Help

  1. Search existing issues: github.com/paragonhq/orsa/issues (opens in a new tab)
  2. Open a new issue with:
    • Orsa version (git rev-parse HEAD)
    • Deployment method (Docker, K8s, Vercel)
    • Relevant logs (redact API keys)
    • Steps to reproduce
  3. Community discussions: github.com/paragonhq/orsa/discussions (opens in a new tab)