Back to Self-Hosting
Troubleshooting Guide
Common issues you might encounter when setting up or running OpenPay, with step-by-step solutions. If you don't find your issue here, check our GitHub Discussions or open an issue.
Jump to section:
Installation & Startup
Docker containers crash on startup
Possible Causes
- Port conflicts with existing services on your machine
- Insufficient Docker resources (RAM/CPU)
- Missing
.envfiles or misconfigured environment variables
Solutions
- Run
docker compose psto check which containers are failing - Check Docker Desktop resources: Settings → Resources → increase RAM to 6GB+
- Verify all
.envfiles exist:ls -la .env payment-system/hyperswitch/.env payment-system/killbill/.env - Check logs:
docker compose logs <service-name>for specific error messages - Stop conflicting services:
netstat -ano | findstr :PORT(Windows) orlsof -i :PORT(Mac/Linux)
make up fails with 'command not found'
Possible Causes
- Make is not installed on your system
- Windows users may not have Make available
Solutions
- Install Make:
winget install GnuWin32.Make(Windows),brew install make(Mac),sudo apt install make(Linux) - Or use Docker Compose directly:
docker compose up -d
Docker Desktop out of space / 'no space left on device'
Possible Causes
- Docker accumulates cached images and build cache over time
- Old containers and volumes not cleaned up
Solutions
- Run
docker system dfto see disk usage - Clean up:
docker system prune -a --volumes(caution: removes all unused containers, images, and volumes) - Or clean only OpenPay:
make clean - Increase Docker disk image size in Docker Desktop → Settings → Resources → Advanced → Disk image size
Hyperswitch
Hyperswitch won't start / health check fails
Possible Causes
- PostgreSQL or Redis not ready when Hyperswitch tries to connect
- Mock Superposition service is not healthy
- Database migrations haven't run (when running standalone)
- Incorrect database credentials in
.env
Solutions
- Ensure PostgreSQL and Redis are healthy first:
docker compose ps postgres redis - Wait longer — Hyperswitch has a 40-second startup grace period
- Check mock-superposition:
curl http://localhost:9999/ - Verify database credentials match between root
.envandpayment-system/hyperswitch/.env - Check logs:
docker compose logs hyperswitch
API returns 401 Unauthorized
Possible Causes
- Missing or incorrect
api-keyheader - API key not set in Hyperswitch environment
Solutions
- Ensure
HYPERSWITCH_API_KEYis set inpayment-system/hyperswitch/.env - Pass the key in requests:
-H 'api-key: your_api_key_here' - Generate a new API key in the Hyperswitch Control Center at
http://localhost:9000
Payments fail with 'connector error'
Possible Causes
- Payment processor (connector) not configured or disabled
- Invalid API credentials for the connector
- Connector is in test mode but you're using live credentials (or vice versa)
- Network connectivity issues between Hyperswitch and the connector API
Solutions
- Verify connector is enabled in Hyperswitch dashboard at
http://localhost:9000 - Double-check connector API keys in the configuration
- Use test cards in test mode (see First Payment guide)
- Check Hyperswitch logs for the exact error from the connector:
docker compose logs hyperswitch - Verify network:
docker compose exec hyperswitch curl -I https://api.paystack.co
PostgreSQL & Database
PostgreSQL fails to start
Possible Causes
- Data directory permissions issue
- Port 5432 already in use by another PostgreSQL instance
- Insufficient disk space
- Corrupted database files from improper shutdown
Solutions
- Check port conflict:
netstat -ano | findstr :5432(Windows) orlsof -i :5432(Mac/Linux) - Check disk space:
docker system df - Remove volume and restart:
docker compose down -v && docker compose up -d(⚠️ deletes all data) - Check logs:
docker compose logs postgres
Services can't connect to PostgreSQL
Possible Causes
- Wrong host — using
localhostinstead of Docker service namepostgres - Password mismatch between service env files
- PostgreSQL still starting up (not yet healthy)
Solutions
- Use Docker service name in internal configs:
postgresnotlocalhost - Verify the password is the same in all env files that reference it
- Wait for PostgreSQL to be healthy:
docker compose ps postgres(look for 'healthy')
Lost database data after restart
Possible Causes
- Docker volumes were removed (docker compose down -v)
- Volume was pruned accidentally
Solutions
- Always use
docker compose downwithout-vto preserve volumes - Set up periodic backups:
docker exec core-postgres pg_dump -U coreplatform hyperswitch > backup.sql - To restore:
docker exec -i core-postgres psql -U coreplatform hyperswitch < backup.sql
NATS & Event Bus
NATS connection refused by consumers
Possible Causes
- NATS server not started or unhealthy
- Wrong NATS URL used by consumer services
- Authentication credentials mismatch
Solutions
- Check NATS is running:
docker compose ps nats - Verify NATS monitoring:
curl http://localhost:8222/healthz - Check connection details:
docker compose logs nats - Verify NATS URL in consumer env files — should be
nats://nats:4222(Docker internal)
Event streams not initialized / missing subjects
Possible Causes
- The
init-streams.shscript hasn't been run - Streams were deleted or expired
Solutions
- Run the initialization script:
./event-bus/nats/scripts/init-streams.sh - Or use Make:
make init-streams - Verify streams exist:
docker compose exec nats nats stream ls - Check stream details:
docker compose exec nats nats stream info payments
Events going to Dead Letter Queue (DLQ)
Possible Causes
- Consumer service is down or not processing events
- Event processing timeout exceeded (30s default)
- Invalid event payload format
Solutions
- Check DLQ:
docker compose exec nats nats stream view DLQ_EVENTS - Investigate the original event and the error reason in the DLQ payload
- Check consumer logs:
docker compose logs tazama-rule-exec - Restart the failing consumer:
docker compose restart tazama-rule-exec
Merchant Dashboard
Dashboard shows blank page or 404
Possible Causes
- Next.js development server not running
- Wrong port — dashboard runs on
3000but Tazama uses3000 - Missing dependencies —
node_modulesnot installed
Solutions
- Start the dashboard:
cd apps/merchant-dashboard && npm run dev - Use port 3002 to avoid conflicts:
npm run dev -- --port 3002 - Install deps:
cd apps/merchant-dashboard && npm install - Clear Next.js cache:
rm -rf .nextand restart
Auth login redirect loop
Possible Causes
- Kinde not configured properly in
.env.local - Redirect URLs don't match Kinde application settings
- Missing Kinde provider configuration
Solutions
- Verify Kinde env vars are set:
cat apps/merchant-dashboard/.env.local | grep KINDE - Check Kinde dashboard → Application → Allowed Callback URLs includes
http://localhost:3000/api/auth/callback - Ensure
KINDE_POST_LOGIN_REDIRECT_URLpoints tohttp://localhost:3000/dashboard - For local dev without Kinde, the auth provider auto-skips when env vars aren't set
Dashboard API calls fail / CORS errors
Possible Causes
- Hyperswitch API not running or unreachable
- API key not configured in dashboard env
- CORS not configured for dashboard origin
Solutions
- Verify Hyperswitch is running:
curl http://localhost:8081/health - Check
HYPERSWITCH_API_KEYinapps/merchant-dashboard/.env.local - For CORS, ensure
HYPERSWITCH_API_URLin dashboard env points tohttp://localhost:8081 - Check browser console for specific CORS error messages
Network & Ports
Port already in use when starting services
Possible Causes
- Another application is using the same port
- Previous Docker containers not fully stopped
Solutions
- Find what's using the port:
netstat -ano | findstr :PORT(Windows) orlsof -i :PORT(Mac/Linux) - Stop the conflicting process or change the port in docker-compose.yml
- Ensure old containers are stopped:
docker compose down - Common conflicts: port 3000 (Tazama vs Dashboard), port 8080 (Traefik), port 5432 (local PostgreSQL)
Can't access services from browser (Windows/WSL2)
Possible Causes
- Docker running in WSL2 but browser on Windows host
- Firewall blocking ports
- Docker bound to wrong interface
Solutions
- Ensure Docker Desktop is configured to expose ports to localhost
- Check Docker Desktop → Settings → Resources → Network → 'Allow privileged port mapping'
- Try accessing via
http://127.0.0.1:PORTinstead oflocalhost - Temporarily disable Windows Firewall to test if it's the cause
- Use
docker compose logsto verify services are bound to 0.0.0.0