This guide covers common issues you might encounter with self-hosted Documenso and their solutions. Start with the diagnostic steps, then find your specific issue below.
# Check if port 3000 is in uselsof -i :3000# Solution: Stop conflicting service or change port# In docker-compose.yml:ports: - "3001:3000" # Map to different host port
Insufficient memory
# Check container logs for OOM (Out Of Memory)docker inspect documenso | jq '.[0].State'# Solution: Increase Docker memory limit# In docker-compose.yml:services: documenso: deploy: resources: limits: memory: 2G
Database migration fails during startup
Symptoms: Logs show “Error: Migration failed”Diagnosis:
-- Grant necessary permissionsdocker exec documenso-db psql -U postgres -c \ "GRANT ALL PRIVILEGES ON DATABASE documenso TO documenso;"
Cannot access Documenso at http://localhost:3000
Symptoms: Connection refused or timeoutDiagnosis:
# Check if container is runningdocker compose ps# Check container logsdocker compose logs documenso# Test from within containerdocker exec documenso curl http://localhost:3000/api/health# Check port bindingdocker compose port documenso 3000
Solutions:
Container not listening on 0.0.0.0
# Ensure HOSTNAME is set correctly# In .env or docker-compose.yml:HOSTNAME=0.0.0.0PORT=3000
Symptoms: Login fails with valid credentialsSolutions:
Check user exists
docker exec documenso-db psql -U documenso -c \ "SELECT id, email, password FROM \"User\" WHERE email = 'user@example.com';"
Reset password
# Use forgot password flow at /forgot-password# Or manually reset in database (not recommended for production)
Check NEXTAUTH_SECRET
# Ensure it hasn't changed since user creationdocker exec documenso env | grep NEXTAUTH_SECRET# If changed, sessions are invalidated - use password reset
Session expires immediately after login
Symptoms: Logged out right after logging inCauses:
NEXTAUTH_URL mismatch
# Check NEXTAUTH_URL matches the URL you're accessing# In .env:NEXTAUTH_URL="https://documenso.example.com" # Must match browser URLNEXT_PUBLIC_WEBAPP_URL="https://documenso.example.com"
Cookie domain issue
# If using reverse proxy, ensure proxy preserves cookies# In nginx:proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;
# Check logs during uploaddocker compose logs -f documenso
Solutions:
File size exceeds limit
# Check configured limitdocker exec documenso env | grep DOCUMENT_SIZE_UPLOAD_LIMIT# Increase limit in .env (in MB)NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=25# If using nginx reverse proxy, also increase:client_max_body_size 25M;
# Error: "Invalid PDF"# Solution: Ensure file is a valid PDF# Try opening in Adobe Reader or another PDF viewer# Re-export from source application
Document signing fails - 'Signing failed' error
Symptoms: Cannot complete signature, error when clicking ‘Sign’Diagnosis:
# Check certificate statuscurl http://localhost:3000/api/health# Look for certificate errors in logsdocker compose logs documenso | grep -i certificate
Solutions:
Signing certificate missing
# Check certificate file existsdocker exec documenso ls -la /opt/documenso/cert.p12# If missing, mount certificate:# In docker-compose.yml:volumes: - ./cert.p12:/opt/documenso/cert.p12:ro# Or set base64 content in .env:NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS="<base64-encoded-cert>"
Certificate passphrase incorrect
# Verify passphrase in .envNEXT_PRIVATE_SIGNING_PASSPHRASE="your-passphrase"# Test certificate manuallyopenssl pkcs12 -info -in cert.p12 -noout# Enter passphrase - should not error
Certificate file permissions
# Ensure Documenso can read the certificatedocker exec documenso cat /opt/documenso/cert.p12 > /dev/null# If permission denied, fix permissions:chmod 644 cert.p12docker compose restart documenso
Signed documents show 'Invalid signature' in Adobe Reader
Symptoms: Adobe shows signature warning or invalidCauses and solutions:
Self-signed certificate not trusted
This is expected for self-signed certificates.To fix:- Use a certificate from a trusted CA- Or manually trust the certificate in Adobe Reader: 1. Open signed PDF 2. Right-click signature → Show Signature Properties 3. Click "Show Certificate" → "Trust" tab 4. Add to Trusted Identities
# Verify SMTP settings in .envNEXT_PRIVATE_SMTP_HOST="smtp.gmail.com"NEXT_PRIVATE_SMTP_PORT=587NEXT_PRIVATE_SMTP_USERNAME="your-email@gmail.com"NEXT_PRIVATE_SMTP_PASSWORD="app-password"NEXT_PRIVATE_SMTP_FROM_ADDRESS="noreply@example.com"NEXT_PRIVATE_SMTP_FROM_NAME="Documenso"# Test SMTP connectiontelnet smtp.gmail.com 587
Emails going to spam
Check recipient spam folder.To improve deliverability:- Configure SPF, DKIM, and DMARC records- Use a verified sending domain- Ensure reverse DNS is set up
Rate limiting by email provider
# Spread out email sending# Upgrade to dedicated email service (SendGrid, Postmark, etc.)# Configure Resend in .env:NEXT_PRIVATE_SMTP_TRANSPORT="smtp-api"NEXT_PRIVATE_RESEND_API_KEY="re_your_api_key"
Symptoms: “Can’t reach database server” or “Connection refused”Solutions:
Database container not running
# Check statusdocker compose ps documenso-db# Start if stoppeddocker compose up -d documenso-db# Check logs for why it stoppeddocker compose logs documenso-db
Incorrect connection string
# Verify DATABASE_URL format# Should be: postgresql://user:password@host:port/database# For Docker Compose:NEXT_PRIVATE_DATABASE_URL="postgresql://documenso:password@documenso-db:5432/documenso"# Note: Use container name (documenso-db), not localhost
Symptoms: “Too many clients already” or “Connection pool exhausted”Diagnosis:
-- Check active connectionsdocker exec documenso-db psql -U documenso -c \ "SELECT COUNT(*) FROM pg_stat_activity WHERE datname = 'documenso';"-- Check max connectionsdocker exec documenso-db psql -U documenso -c \ "SHOW max_connections;"
Solutions:
Increase max_connections
# In docker-compose.yml:services: documenso-db: command: postgres -c max_connections=200docker compose up -d documenso-db
Close idle connections
-- Find and kill idle connections (PostgreSQL 14+)docker exec documenso-db psql -U documenso -c \ "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'documenso' AND state = 'idle' AND state_change < NOW() - INTERVAL '5 minutes';"
Use connection pooling
# Use PgBouncer for connection pooling# Add to docker-compose.yml:pgbouncer: image: pgbouncer/pgbouncer environment: DATABASES: documenso=postgres://documenso:password@documenso-db:5432/documenso POOL_MODE: transaction MAX_CLIENT_CONN: 1000 DEFAULT_POOL_SIZE: 20# Update Documenso to connect via PgBouncer:NEXT_PRIVATE_DATABASE_URL="postgresql://documenso:password@pgbouncer:5432/documenso"
Slow database queries
Symptoms: Documenso slow to load, timeoutsDiagnosis:
-- Enable pg_stat_statementsdocker exec documenso-db psql -U documenso -c \ "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"-- Find slow queriesdocker exec documenso-db psql -U documenso -c \ "SELECT query, calls, mean_exec_time, max_exec_time FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;"
Solutions:
Add missing indexes
-- Check for missing indexesdocker exec documenso-db psql -U documenso -c \ "SELECT schemaname, tablename, attname, n_distinct, correlation FROM pg_stats WHERE schemaname = 'public' AND n_distinct > 100 ORDER BY n_distinct DESC;"-- Indexes should already exist from migrations-- If missing, run migrations:docker exec documenso npx prisma migrate deploy --schema ./packages/prisma/schema.prisma
# Check container statsdocker stats documenso# View top processes in containerdocker exec documenso top
Solutions:
Inefficient queries - See database slow query diagnosis above
PDF processing bottleneck
# PDF processing is CPU-intensive# Increase CPU limits in docker-compose.yml:services: documenso: deploy: resources: limits: cpus: '4' # Increase from default
Background jobs overwhelming
# Check job provider configurationdocker exec documenso env | grep JOBS_PROVIDER# If using local jobs, ensure not processing too many concurrently
High memory usage / OOM killed
Symptoms: Container crashes, logs show “Killed” or OOMDiagnosis:
# Enable Node.js memory profiling# In docker-compose.yml:environment: NODE_OPTIONS: "--max-old-space-size=4096"
Large document files
# If processing very large PDFs, consider:# - Limiting document size (NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT)# - Using S3 storage instead of database storage# - Scaling horizontally with multiple instances
Disk space full
Symptoms: “No space left on device”Diagnosis:
# Check disk usagedf -h# Find large directoriesdu -h / | sort -rh | head -20# Check Docker disk usagedocker system df
-- Find old completed documentsdocker exec documenso-db psql -U documenso -c \ "SELECT id, title, status, pg_size_pretty(length(data)) as size FROM \"Document\" JOIN \"DocumentData\" ON \"Document\".\"documentDataId\" = \"DocumentData\".id WHERE status = 'COMPLETED' AND \"completedAt\" < NOW() - INTERVAL '1 year' ORDER BY length(data) DESC LIMIT 20;"# Manually export and delete if needed
# Ensure these are set in .env:NEXT_PUBLIC_WEBAPP_URL="https://documenso.example.com" # HTTPSNEXTAUTH_URL="https://documenso.example.com" # HTTPS# In nginx, pass protocol header:proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header X-Forwarded-Ssl on;
SSL certificate errors
Symptoms: “Certificate not valid” or “NET::ERR_CERT_AUTHORITY_INVALID”Solutions: