Operations
Troubleshooting
Common issues and their solutions.
Common Issues
| Problem | Solution |
|---|---|
| Port 25 blocked | Contact your VPS provider to unblock outbound port 25. Test with nc -zv gmail-smtp-in.l.google.com 25 |
| DKIM not verifying | Wait 24-48h for DNS propagation. Check with dig TXT postal._domainkey.yourdomain.com |
| License activation fails | Ensure APP_ENV=production is set. Check network connectivity to api.dodopayments.com |
| Emails going to spam | Check SPF/DKIM/DMARC are all green in dashboard. Warm up mailboxes first (2-3 weeks) |
| Server won't start | Check logs: docker compose logs cleanmails. Usually missing MASTER_KEY |
| SQLite locked errors | Ensure only one instance is running. WAL mode handles concurrency automatically |
| SMTP test fails on sender creation | Verify host/port/credentials. For Mailcow-managed senders, this is handled automatically |
| Campaign not sending | Check: status is "running", schedule window is active, senders have remaining daily limit, leads are not unsubscribed |
| Warmup not working | Need at least 2 senders in warmup mode. Check both have status "ready" |
| AI tags showing fallback | Check Gemini API key in Settings → AI. Verify key is valid at aistudio.google.com |
Checking Logs
Docker Compose deployment
bash
# All services
docker compose logs -f
# Just Cleanmails
docker compose logs -f cleanmails
# Just mail server
docker compose logs -f mailserver
# Last 100 lines
docker compose logs --tail=100 cleanmailsSystemd deployment
bash
# Live logs
journalctl -u cleanmails -f
# Last hour
journalctl -u cleanmails --since "1 hour ago"
# Application log file
tail -f /opt/cleanmails/cleanmails.logHealth Check
bash
# Basic health
curl http://localhost:8080/health
# Detailed outreach health (port 25, queues, runtime)
curl http://localhost:8080/v1/outreach/health
# Network check (port 25 status)
curl http://localhost:8080/v1/outreach/health | jq '.checks.port_25_outgoing'Database Issues
Corrupted database
bash
# Stop the service
docker compose down
# Check integrity
sqlite3 /opt/cleanmails/data/cleanmails.db "PRAGMA integrity_check;"
# If corrupted, restore from backup
cp /backups/cleanmails-YYYYMMDD.db /opt/cleanmails/data/cleanmails.db
# Restart
docker compose up -dDatabase is locked
This usually means multiple processes are trying to write simultaneously. Cleanmails uses a single-connection pool to prevent this, but if you're running multiple instances:
bash
# Check for multiple processes
ps aux | grep bulkserver
# Kill duplicates (keep only one)
kill <PID>Email Deliverability Issues
Check DNS records
bash
# SPF
dig TXT yourdomain.com
# DKIM
dig TXT postal._domainkey.yourdomain.com
# DMARC
dig TXT _dmarc.yourdomain.com
# MX
dig MX yourdomain.comCheck IP blacklists
Visit MXToolbox Blacklist Check and enter your server IP.
Resetting Admin Password
If you've lost your admin password, you can reset it directly in the database:
Direct database access
This requires SSH access to your server. The password must be bcrypt-hashed.
bash
# Generate a bcrypt hash for your new password
docker exec cleanmails sh -c 'echo -n "YourNewPassword" | htpasswd -niBC 10 "" | cut -d: -f2'
# Update in database
sqlite3 /opt/cleanmails/data/cleanmails.db "UPDATE users SET password='BCRYPT_HASH_HERE' WHERE role='admin';"
# Restart to clear sessions
docker compose restart cleanmailsGetting Help
If you're still stuck:
- Use the AI Copilot in your dashboard — it has full context of your workspace
- Check the Support page for direct assistance
- Include your logs and health check output when reporting issues