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.
The application will not start
Section titled “The application will not start”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.
Everyone is signed out after a deployment
Section titled “Everyone is signed out after a deployment”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.
Sign-in problems
Section titled “Sign-in problems”| 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.
Uploads
Section titled “Uploads”The file is rejected before it uploads
Section titled “The file is rejected before it uploads”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.
The file is too large
Section titled “The file is too large”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.
Documents
Section titled “Documents”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.
Preview is unavailable
Section titled “Preview is unavailable”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:
- Soft delete moves an item to the recycle bin. Nothing is removed until retention purges it.
- 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.
Search
Section titled “Search”Search is slow, or matches feel imprecise
Section titled “Search is slow, or matches feel imprecise”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.
A document is missing from results
Section titled “A document is missing from results”Two likely reasons, in order:
- 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.
- Text not yet extracted. Content search matches extracted text. A document whose OCR has not run yet matches on metadata only.
OCR and text extraction
Section titled “OCR and text extraction”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 and email
Section titled “Notifications and email”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.
- Confirm background jobs are running.
- Send a test message from the SMTP settings screen. It exercises the same path.
- Check the recipient’s own notification email preferences - a user can turn categories off.
See Email.
Workflows
Section titled “Workflows”| 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. |
After restoring from backup
Section titled “After restoring from backup”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.
Reading the logs
Section titled “Reading the logs”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 -
429and503responses 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.
Related
Section titled “Related”- Security hardening - the key ring, headers, and rate limits.
- Background jobs - what runs, and how often.
- Database deployment - the two-principal model and the schema ledger.
- Performance and tuning - measured numbers behind the search guidance above.