Skip to main content

Overview

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.

Diagnostic Steps

When troubleshooting any issue, follow these steps:
1

Check health endpoint

curl http://localhost:3000/api/health
This reveals database and certificate status issues immediately.
2

Check logs

# Docker
docker compose logs documenso --tail=100

# PM2
pm2 logs documenso --lines 100

# Systemd
journalctl -u documenso -n 100 --no-pager
Look for errors (level 50+) and warnings.
3

Verify environment variables

# Docker
docker exec documenso env | grep NEXT_

# Check .env file
cat .env | grep -v '^#' | grep -v '^$'
Ensure all required variables are set correctly.
4

Check resource usage

# Docker
docker stats documenso documenso-db

# System
top
df -h  # Disk space
free -m  # Memory
5

Test database connectivity

# From within container
docker exec documenso-db psql -U documenso -c 'SELECT 1'

# From Documenso container
docker exec documenso npx prisma db execute --stdin <<< 'SELECT 1' --schema ./packages/prisma/schema.prisma

Installation and Startup Issues

Symptoms: Container starts and exits within secondsCommon causes:
  1. Database connection failure
    # Check logs for database errors
    docker compose logs documenso | grep -i "database\|postgres\|prisma"
    
    # Common error: "Can't reach database server"
    # Solution: Verify DATABASE_URL is correct
    # Ensure database container is running
    docker compose ps documenso-db
    
  2. Missing environment variables
    # Check for required variables
    docker exec documenso env | grep NEXT_PRIVATE_ENCRYPTION_KEY
    docker exec documenso env | grep NEXTAUTH_SECRET
    
    # Solution: Add to .env file
    echo 'NEXT_PRIVATE_ENCRYPTION_KEY="your-32-char-key"' >> .env
    echo 'NEXTAUTH_SECRET="your-secret"' >> .env
    docker compose restart documenso
    
  3. Port conflict
    # Check if port 3000 is in use
    lsof -i :3000
    
    # Solution: Stop conflicting service or change port
    # In docker-compose.yml:
    ports:
      - "3001:3000"  # Map to different host port
    
  4. 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
    
Symptoms: Logs show “Error: Migration failed”Diagnosis:
# Check migration status
docker exec documenso npx prisma migrate status --schema ./packages/prisma/schema.prisma
Solutions:
  1. Migration timeout (large database)
    -- Increase timeout
    docker exec documenso-db psql -U documenso -c \
      "ALTER DATABASE documenso SET statement_timeout = '600000';"
    
    docker compose restart documenso
    
  2. Failed migration (partially applied)
    # Mark migration as rolled back
    docker exec documenso npx prisma migrate resolve \
      --rolled-back "20260304000000_migration_name" \
      --schema ./packages/prisma/schema.prisma
    
    # Retry migration
    docker exec documenso npx prisma migrate deploy \
      --schema ./packages/prisma/schema.prisma
    
  3. Database permissions issue
    -- Grant necessary permissions
    docker exec documenso-db psql -U postgres -c \
      "GRANT ALL PRIVILEGES ON DATABASE documenso TO documenso;"
    
Symptoms: Connection refused or timeoutDiagnosis:
# Check if container is running
docker compose ps

# Check container logs
docker compose logs documenso

# Test from within container
docker exec documenso curl http://localhost:3000/api/health

# Check port binding
docker compose port documenso 3000
Solutions:
  1. Container not listening on 0.0.0.0
    # Ensure HOSTNAME is set correctly
    # In .env or docker-compose.yml:
    HOSTNAME=0.0.0.0
    PORT=3000
    
  2. Firewall blocking access
    # Check firewall rules
    sudo ufw status
    
    # Allow port 3000
    sudo ufw allow 3000/tcp
    
  3. Docker network issue
    # Recreate network
    docker compose down
    docker network prune
    docker compose up -d
    

Authentication and Login Issues

Symptoms: Login fails with valid credentialsSolutions:
  1. Check user exists
    docker exec documenso-db psql -U documenso -c \
      "SELECT id, email, password FROM \"User\" WHERE email = 'user@example.com';"
    
  2. Reset password
    # Use forgot password flow at /forgot-password
    # Or manually reset in database (not recommended for production)
    
  3. Check NEXTAUTH_SECRET
    # Ensure it hasn't changed since user creation
    docker exec documenso env | grep NEXTAUTH_SECRET
    
    # If changed, sessions are invalidated - use password reset
    
Symptoms: Logged out right after logging inCauses:
  1. NEXTAUTH_URL mismatch
    # Check NEXTAUTH_URL matches the URL you're accessing
    # In .env:
    NEXTAUTH_URL="https://documenso.example.com"  # Must match browser URL
    NEXT_PUBLIC_WEBAPP_URL="https://documenso.example.com"
    
  2. 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;
    
  3. Database connection lost
    # Check health endpoint
    curl http://localhost:3000/api/health
    
    # Verify database connectivity
    docker exec documenso-db psql -U documenso -c 'SELECT 1'
    
Symptoms: OAuth redirect fails or shows errorSolutions:
  1. Check OAuth configuration
    # Verify credentials are set
    docker exec documenso env | grep GOOGLE_CLIENT
    docker exec documenso env | grep MICROSOFT_CLIENT
    
  2. Verify redirect URI in OAuth app
    # Should be:
    https://your-domain.com/api/auth/callback/google
    https://your-domain.com/api/auth/callback/microsoft
    
    # NOT:
    http://localhost:3000/api/auth/callback/google  # Wrong domain
    
  3. Check OAuth app status
    • Ensure OAuth app is published/approved
    • Verify scopes requested match what’s configured
    • Check OAuth app isn’t suspended or disabled

Document and Signing Issues

Symptoms: Document upload failsDiagnosis:
# Check logs during upload
docker compose logs -f documenso
Solutions:
  1. File size exceeds limit
    # Check configured limit
    docker 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;
    
  2. Storage backend issue For database storage (default):
    # Check database connection
    curl http://localhost:3000/api/health
    
    # Check disk space
    df -h
    
    For S3 storage:
    # Verify S3 credentials
    docker exec documenso env | grep UPLOAD
    
    # Test S3 connection
    docker exec documenso aws s3 ls s3://your-bucket/ \
      --endpoint-url $NEXT_PRIVATE_UPLOAD_ENDPOINT
    
  3. Invalid PDF file
    # Error: "Invalid PDF"
    # Solution: Ensure file is a valid PDF
    # Try opening in Adobe Reader or another PDF viewer
    # Re-export from source application
    
Symptoms: Cannot complete signature, error when clicking ‘Sign’Diagnosis:
# Check certificate status
curl http://localhost:3000/api/health

# Look for certificate errors in logs
docker compose logs documenso | grep -i certificate
Solutions:
  1. Signing certificate missing
    # Check certificate file exists
    docker 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>"
    
  2. Certificate passphrase incorrect
    # Verify passphrase in .env
    NEXT_PRIVATE_SIGNING_PASSPHRASE="your-passphrase"
    
    # Test certificate manually
    openssl pkcs12 -info -in cert.p12 -noout
    # Enter passphrase - should not error
    
  3. Certificate file permissions
    # Ensure Documenso can read the certificate
    docker exec documenso cat /opt/documenso/cert.p12 > /dev/null
    
    # If permission denied, fix permissions:
    chmod 644 cert.p12
    docker compose restart documenso
    
See the Signing Certificate guide for setup details.
Symptoms: Adobe shows signature warning or invalidCauses and solutions:
  1. 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
    
  2. Certificate expired
    # Check certificate validity
    openssl pkcs12 -in cert.p12 -nokeys -passin pass:$PASSPHRASE | \
      openssl x509 -noout -dates
    
    # Renew certificate if expired
    
  3. Using legacy signing subfilter
    # Ensure using modern ETSI.CAdES.detached (default)
    # Only set this if you need legacy compatibility:
    NEXT_PRIVATE_USE_LEGACY_SIGNING_SUBFILTER="false"
    
Symptoms: Recipients don’t receive signing emailsDiagnosis:
# Check logs for email errors
docker compose logs documenso | grep -i "email\|smtp\|mail"
Solutions:
  1. SMTP configuration incorrect
    # Verify SMTP settings in .env
    NEXT_PRIVATE_SMTP_HOST="smtp.gmail.com"
    NEXT_PRIVATE_SMTP_PORT=587
    NEXT_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 connection
    telnet smtp.gmail.com 587
    
  2. 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
    
  3. 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"
    
See the Email Configuration guide for details.

Database Issues

Symptoms: “Can’t reach database server” or “Connection refused”Solutions:
  1. Database container not running
    # Check status
    docker compose ps documenso-db
    
    # Start if stopped
    docker compose up -d documenso-db
    
    # Check logs for why it stopped
    docker compose logs documenso-db
    
  2. 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
    
  3. Database not accepting connections
    # Check PostgreSQL is listening
    docker exec documenso-db pg_isready -U documenso
    
    # Check postgresql.conf
    docker exec documenso-db cat /var/lib/postgresql/data/postgresql.conf | grep listen_addresses
    # Should be: listen_addresses = '*'
    
Symptoms: “Too many clients already” or “Connection pool exhausted”Diagnosis:
-- Check active connections
docker exec documenso-db psql -U documenso -c \
  "SELECT COUNT(*) FROM pg_stat_activity WHERE datname = 'documenso';"

-- Check max connections
docker exec documenso-db psql -U documenso -c \
  "SHOW max_connections;"
Solutions:
  1. Increase max_connections
    # In docker-compose.yml:
    services:
      documenso-db:
        command: postgres -c max_connections=200
    
    docker compose up -d documenso-db
    
  2. 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';"
    
  3. 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"
    
Symptoms: Documenso slow to load, timeoutsDiagnosis:
-- Enable pg_stat_statements
docker exec documenso-db psql -U documenso -c \
  "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"

-- Find slow queries
docker 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:
  1. Add missing indexes
    -- Check for missing indexes
    docker 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
    
  2. Run VACUUM and ANALYZE
    -- Update statistics and clean up
    docker exec documenso-db psql -U documenso -c \
      "VACUUM ANALYZE;"
    
  3. Increase shared_buffers
    # In docker-compose.yml:
    services:
      documenso-db:
        command: |
          postgres
          -c shared_buffers=256MB
          -c effective_cache_size=1GB
          -c maintenance_work_mem=64MB
          -c checkpoint_completion_target=0.9
    
    docker compose up -d documenso-db
    

Performance Issues

Diagnosis:
# Check container stats
docker stats documenso

# View top processes in container
docker exec documenso top
Solutions:
  1. Inefficient queries - See database slow query diagnosis above
  2. 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
    
  3. Background jobs overwhelming
    # Check job provider configuration
    docker exec documenso env | grep JOBS_PROVIDER
    
    # If using local jobs, ensure not processing too many concurrently
    
Symptoms: Container crashes, logs show “Killed” or OOMDiagnosis:
# Check memory usage
docker stats documenso

# Check OOM kill events
dmesg | grep -i "out of memory"
docker inspect documenso | jq '.[0].State'
Solutions:
  1. Increase memory limit
    # docker-compose.yml
    services:
      documenso:
        deploy:
          resources:
            limits:
              memory: 4G  # Increase from 2G
            reservations:
              memory: 2G
    
  2. Memory leak investigation
    # Enable Node.js memory profiling
    # In docker-compose.yml:
    environment:
      NODE_OPTIONS: "--max-old-space-size=4096"
    
  3. 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
    
Symptoms: “No space left on device”Diagnosis:
# Check disk usage
df -h

# Find large directories
du -h / | sort -rh | head -20

# Check Docker disk usage
docker system df
Solutions:
  1. Clean up Docker resources
    # Remove unused images
    docker image prune -a
    
    # Remove unused volumes
    docker volume prune
    
    # Remove build cache
    docker builder prune
    
    # Clean everything (careful!)
    docker system prune -a --volumes
    
  2. Rotate logs
    # In docker-compose.yml:
    services:
      documenso:
        logging:
          driver: "json-file"
          options:
            max-size: "10m"
            max-file: "3"
    
  3. Archive old documents
    -- Find old completed documents
    docker 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
    

Reverse Proxy and SSL Issues

Symptoms: Nginx/Caddy shows 502 errorSolutions:
  1. Documenso not running
    docker compose ps documenso
    # If not running, check logs and start
    
  2. Incorrect proxy configuration
    # Nginx - ensure proxy_pass uses correct port
    location / {
      proxy_pass http://localhost:3000;  # or container name
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;
    }
    
  3. Docker network isolation
    # If proxy is in different network, add it to Documenso network
    # In docker-compose.yml:
    networks:
      default:
        name: documenso-network
        external: true
    
Symptoms: Browser shows mixed content warningsSolutions:
# Ensure these are set in .env:
NEXT_PUBLIC_WEBAPP_URL="https://documenso.example.com"  # HTTPS
NEXTAUTH_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;
Symptoms: “Certificate not valid” or “NET::ERR_CERT_AUTHORITY_INVALID”Solutions:
  1. Let’s Encrypt certificate
    # Install certbot
    sudo apt install certbot python3-certbot-nginx
    
    # Obtain certificate
    sudo certbot --nginx -d documenso.example.com
    
    # Auto-renewal is configured automatically
    sudo certbot renew --dry-run
    
  2. Self-signed certificate (development only)
    # Generate self-signed cert
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
      -keyout /etc/ssl/private/documenso.key \
      -out /etc/ssl/certs/documenso.crt
    
    # Configure in nginx:
    ssl_certificate /etc/ssl/certs/documenso.crt;
    ssl_certificate_key /etc/ssl/private/documenso.key;
    

Update and Migration Issues

See the Updates guide for update-specific troubleshooting.
See Rollback Procedures in the Updates guide.
See Migration Failures in the Updates guide.

Getting Help

If you can’t resolve your issue:

1. Gather diagnostic information

#!/bin/bash
# generate-diagnostics.sh

DIAG_FILE="documenso-diagnostics-$(date +%Y%m%d-%H%M%S).txt"

echo "Documenso Diagnostics" > $DIAG_FILE
echo "Generated: $(date)" >> $DIAG_FILE
echo "" >> $DIAG_FILE

echo "=== Container Status ===" >> $DIAG_FILE
docker compose ps >> $DIAG_FILE 2>&1
echo "" >> $DIAG_FILE

echo "=== Health Check ===" >> $DIAG_FILE
curl -s http://localhost:3000/api/health >> $DIAG_FILE 2>&1
echo "" >> $DIAG_FILE

echo "=== Recent Logs ===" >> $DIAG_FILE
docker compose logs --tail=100 documenso >> $DIAG_FILE 2>&1
echo "" >> $DIAG_FILE

echo "=== Environment (sanitized) ===" >> $DIAG_FILE
docker exec documenso env | grep NEXT_ | sed 's/=.*/=***/' >> $DIAG_FILE 2>&1
echo "" >> $DIAG_FILE

echo "=== Disk Usage ===" >> $DIAG_FILE
df -h >> $DIAG_FILE 2>&1
echo "" >> $DIAG_FILE

echo "=== Docker Stats ===" >> $DIAG_FILE
docker stats --no-stream >> $DIAG_FILE 2>&1

echo "Diagnostics saved to: $DIAG_FILE"

2. Search existing issues

Search GitHub issues for similar problems:

3. Ask for help

4. Include in your help request

  • Documenso version (check logs or package.json)
  • Deployment method (Docker, bare metal, K8s)
  • OS and version
  • Error messages from logs
  • Steps to reproduce
  • What you’ve already tried
  • Output from diagnostic script above (sanitize secrets!)
Never share sensitive information (passwords, API keys, signing certificates) in public issues or Discord. Sanitize logs before sharing.

Monitoring

Set up monitoring to catch issues early

Updates

Safely update Documenso

Backups

Backup and restore procedures

GitHub Issues

Report bugs and request features