Skip to content

Troubleshooting

Most Docsentry failures are deliberate. The system prefers refusing to start, or refusing to serve, over continuing in a state where the damage would surface later and be harder to attribute. That makes the messages below diagnostic rather than mysterious - each one names the condition it detected.

Work down from the section that matches when the failure happens.

Startup validation runs before the host binds a port. If any of these fire, nothing is served at all - which is the point.

DataProtection:KeyPath must be set outside Development

Section titled “DataProtection:KeyPath must be set outside Development”

The Data Protection key ring encrypts authentication cookies, the antivirus API key, and the other protected settings. Outside Development, Docsentry refuses to invent a location for it, because the default location is inside the content root - where a deployment would silently recreate it on every release and sign every user out.

Set DataProtection:KeyPath to an absolute path on durable storage, outside the content root, and back it up. A relative path is rejected with the same class of error.

See Security hardening.

The runtime database principal is over-privileged

Section titled “The runtime database principal is over-privileged”

Docsentry checks at startup that the identity in ConnectionStrings:DefaultConnection is a member of DocsentryAppRole and not a member of db_owner. The message names which of the two conditions failed.

This is the two-principal model: the identity that deploys schema and the identity that runs the application are deliberately different, so a compromised application cannot rewrite its own audit log. Point the connection string at the least-privilege login, not at the account used for deployment.

See Database deployment.

The host exits when Workflows:Engine is Elsa

Section titled “The host exits when Workflows:Engine is Elsa”

The Elsa engine needs its own deploy script applied. If it has not been, the application refuses to start rather than starting successfully and failing at the first workflow - long after anyone would connect the two events.

Either apply the script, or set Workflows:Engine back to Dapper, which is the default and needs nothing beyond the standard schema.

A deploy script fails with a checksum mismatch

Section titled “A deploy script fails with a checksum mismatch”

Every applied script’s SHA-256 is recorded in dbo.DmsSchemaVersions and re-validated on replay. A mismatch means a script that was already applied has been edited since.

Do not “fix” the ledger. Restore the script to the bytes that were applied, and ship the correction as a new numbered script - the deployment sequence is forward-only by design.

The Data Protection key ring was not preserved. Cookies issued by the previous instance cannot be decrypted by the new one, so every session is invalid.

Confirm DataProtection:KeyPath points outside the content root and survives the release, and that the key ring is included in your backups. It is a credential: restoring a database without it does not restore working sessions.

Symptom Cause What to do
Correct password rejected, account unusable Lockout after repeated failures Wait out the lockout window, or clear it as an administrator.
429 Too Many Requests at the sign-in form Rate limiting, metered per account and per IP Wait for the interval named in Retry-After.
Sign-in works locally, fails behind a proxy Forwarded headers not configured, so the app sees the proxy’s IP Configure the known proxies and networks; the fail-closed default is to ignore untrusted headers.

The per-account and per-IP buckets are chained deliberately: metering on IP alone locks out a whole office when one person forgets their password. See Security hardening.

The upload allowlist checks three things and requires all three to agree: the file extension, the declared MIME type, and the content sniffed from the first bytes. A .pdf that is really a ZIP fails, and so does a genuine PDF sent with the wrong content type.

Check Upload allowlist for the permitted set, and the folder’s own upload policy, which can narrow the global list further but never widen it.

Size limits apply per content type and can be set per folder. The effective limit for a folder is resolvable at /api/v1/folders/{id}/effective-upload-policy - use that rather than guessing which layer refused.

An upload stops partway and cannot be resumed

Section titled “An upload stops partway and cannot be resumed”

Upload sessions are resumable, but abandoned ones are swept by a background job. Once swept, the session id is gone and the upload must start again. See Uploading.

Download is refused on a document that clearly exists

Section titled “Download is refused on a document that clearly exists”

The version has not cleared antivirus scanning. Docsentry is fail-closed: unscanned content is never served, because the alternative is serving malware during the window before a scan completes.

Check the scan status on the document. If it is stuck rather than failed, the scanning job is not running - see Background jobs. If the file genuinely failed a scan, it is in quarantine and is not going to be served.

Previews are generated, not stored, so an unavailable preview means generation did not happen.

Document kind Needs If missing
Office formats LibreOffice on the host The preview is unavailable; the original still downloads.
PDF and images Built-in rendering Check the preview generation job.

LibreOffice is discovered automatically at the usual install locations. If it is installed somewhere unusual, configure the path explicitly. See Previews.

Deleting documents does not free disk space

Section titled “Deleting documents does not free disk space”

This is correct behaviour, not a fault. Two mechanisms are in play:

  1. Soft delete moves an item to the recycle bin. Nothing is removed until retention purges it.
  2. Content-addressed storage stores a file once under a path derived from its hash, and references it from every document with those bytes. Removing one document does not remove the blob while another still points at it.

See Governance and retention.

Docsentry probes for a full-text index at startup and caches the answer for five minutes. If no index is available it falls back to a LIKE predicate. That is correct but not sargable - it scans rather than seeks, and the cost grows with the corpus.

On a measured 100-VU run, search under fallback answered at a p95 of 426 ms against 38 ms for folder listing - an order of magnitude, attributable entirely to the missing index. Install and populate full-text search on the SQL Server instance to remove it.

Two likely reasons, in order:

  1. Permission trimming. Results are trimmed rather than marked forbidden. A document you cannot read does not appear at all - it is not hidden with a message. Check effective permissions on it.
  2. Text not yet extracted. Content search matches extracted text. A document whose OCR has not run yet matches on metadata only.

The status field distinguishes the two failure modes, and they need different fixes:

Status Meaning
Pending The job never ran. Background processing is not running, or is backed up.
Failed The job ran and the OCR engine could not be reached or could not process the file.

Pending points at Background jobs. Failed points at the Tesseract installation and its language data - Docsentry uses eng+ara, and a missing Arabic data file fails the whole extraction, not just the Arabic part.

Notifications are written to a durable outbox and sent by a background job, so a message that has not arrived is either not yet drained or failing to send.

  1. Confirm background jobs are running.
  2. Send a test message from the SMTP settings screen. It exercises the same path.
  3. Check the recipient’s own notification email preferences - a user can turn categories off.

See Email.

Symptom Likely cause
A definition cannot be started on a document The definition is Draft or Archived; only Active definitions start.
A task is in nobody’s inbox Its assignee has left. Reconciliation reassigns these, but only when it runs.
A step is marked Escalated It was outstanding beyond the configured window. That is the mechanism working.
A folder’s documents are not entering approval The folder has no approver workflow bound. Manual starts depend on someone remembering.

The failure that catches people out is orphaned database users. Restoring a database onto a different server carries the users but not their server-level logins, so the mapping breaks. The application then fails at startup with an authentication error that looks nothing like a restore problem.

Re-map each user to its login (ALTER USER … WITH LOGIN = …) after the restore, then confirm the runtime principal is still a DocsentryAppRole member and still not db_owner.

Also restore, separately: the content-addressed storage tree, and the Data Protection key ring. The database alone is not a working system.

Docsentry logs structured events. When something is wrong, the useful ones are:

  • Startup validation - every refusal above is logged before it is thrown.
  • Background job execution - a job that is not appearing is not running.
  • Rate limiting and shedding - 429 and 503 responses are logged with the bucket that produced them.

A health probe is available at /api/v1/health. It is anonymous and exempt from rate limiting, so it stays answerable when the rest of the application is shedding load.