Skip to content

Troubleshooting

Common issues and how to diagnose them. Run commands from the compose directory.

Terminal window
docker compose ps # what's up / healthy / restarting
docker compose logs --tail=100 qsign-backend
docker compose logs --tail=50 nginx esign db
curl -sI https://sign.example.com/health # 200 expected

Backend won’t start / restarts in a loop

Section titled “Backend won’t start / restarts in a loop”
  • Missing SECRET_KEY → the backend refuses to boot. Ensure it’s set in config/backend.env.
  • Database not reachable → check db is healthy (docker compose ps), that DB_HOST/PORT/USER/PASSWORD/DB_NAME match config/db.env, and that the DB finished initializing on first run (MySQL takes longer the first time). The backend depends_on the DB healthcheck.
  • Migrations failing → read docker compose logs qsign-backend. If you just upgraded, consult the release notes; if needed, restore the pre-upgrade DB dump and retry.
  • Bad settings moduleDJANGO_SETTINGS_MODULE must point at the intended settings.
  • REACT_APP_LOGIN_PASSWORD_KEYBACKEND_LOGIN_PASSWORD_KEY. The login password is transport-encoded with the frontend key and decoded with the backend key; they must match exactly. This is the most common login failure.
  • “Logged in on another device” / blocked: QSign enforces a single active session per user. Log out elsewhere, or an admin can clear the user’s session token.
  • Account locked: too many failed attempts. An admin must unlock the user.
  • CORS error in the browser console: the request origin isn’t allowed — confirm ALLOWED_HOSTS / the configured CORS origins include your domain and you’re using HTTPS.

404 on /backend/othercompanyapi (or similar prefix)

Section titled “404 on /backend/othercompanyapi (or similar prefix)”

The bare prefix has no page — that’s expected. Use a real endpoint, e.g. /backend/othercompanyapi/openapi.json. If every /backend/* path 404s, the nginx /backend/qsign-backend:8000 route or prefix-strip is misconfigured.

  • 413 / “request entity too large”: raise client_max_body_size in the nginx config (and any upstream LB limit) and reload nginx.
  • Office→PDF conversion errors: LibreOffice runs in the backend container; check backend logs and host CPU/RAM. Large/complex documents need more resources.
  • Upload rejected as infected/too large: ClamAV flagged it (if AV is enabled) — check docker compose logs clamav and the backend activity log.

Email not delivered (signing invites/reminders)

Section titled “Email not delivered (signing invites/reminders)”
  • Confirm an email provider is configured (RESEND_API_KEY or ZEPTOMAIL_TOKEN) and the DEFAULT_FROM_EMAIL domain is verified with that provider.
  • Check backend logs for send errors; verify outbound network egress to the provider API.
  • Headless/API integrations may intentionally suppress emails (is_mail_required: false) — use the returned signing links instead.
  • e-Signature/tamper-seal: ensure the esign service is up and reachable (docker compose logs esign) and the document storage volume is writable by both backend and esign.
  • Aadhaar eSign: verify outbound egress to the NSDL/Protean gateway, that ASP_ID / ESIGN_* URLs / the signing P12_* cert are correct on the esign service, and that the callback URL (response_url_esign) is publicly reachable. Signature-validation errors in the logs usually mean a cert/URL/response mismatch.
  • DSC: confirm the certificate (and, for token signing, the agent) is available and the signing session hasn’t expired (sessions are short-lived); if using a TSA, confirm egress to the TSA endpoint.
  • 401/400: missing or wrong X-Api-Key. Regenerate in the Developer portal if unsure.
  • 403: the account is suspended or its subscription has expired — an operator action in the super-admin console.
  • 429: rate limit or monthly quota exceeded — check X-RateLimit-* headers and /usage/summary/; honor Retry-After.
  • The URL must be a public https:// endpoint (internal/loopback URLs are rejected by SSRF protection).
  • Inspect delivery attempts at GET /webhook/deliveries/.
  • Verify your endpoint responds 2xx quickly and that your HMAC verification matches (compute over the raw body with the exact secret).
  • Solr may be empty or out of sync. Rebuild: docker compose exec qsign-backend /opt/venv/bin/python manage.py reindex_solr.
  • Confirm SOLR_BASE_URL / SOLR_CORE are correct and the solr container is up.
  • The API throttle uses Redis and fails open if Redis is down (so limits aren’t enforced during a Redis outage). Check redis is up if you expect limits to apply.
  • ACME (Let’s Encrypt) fails: port 80 must be reachable from the internet for the webroot challenge; check DNS points at the host and the certbot webroot path matches the nginx /.well-known/acme-challenge/ location.
  • Cert expired: renew (certbot) or replace your CA cert, then docker compose restart nginx. Monitor expiry proactively.
Terminal window
# Exec into the backend (use the venv python):
docker compose exec qsign-backend /opt/venv/bin/python manage.py shell
# Check registered cron jobs:
docker compose exec qsign-backend /opt/venv/bin/python manage.py crontab show
# DB console:
docker compose exec db sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" qsign'
# Restart a single service:
docker compose restart qsign-backend

When opening a support ticket, include: the QSign image versions (docker compose images), relevant log excerpts (docker compose logs --since 1h <service>), the failing request/response (redact secrets), and which optional integrations are enabled. Never share secret values, certificates, or full env files.