Site icon EfmSoft

What does HRESULT 0xC80003F9 (hrRecordDeleted) mean?

 
Previous Next
hrTooManyKeys hrReadVerifyFailure

hrRecordDeleted

Locate the failure in the Jet call chain

For hrRecordDeleted, the useful clue is the engine object that rejected the operation and the state it had reached. The decisive boundary is the cursor refers to a row that was deleted after it became the current record.

This result is the legacy Directory Service backup/restore HRESULT form of the ESE condition normally written as JET_errRecordDeleted. Preserve the original value 0xC80003F9 when a wrapper also exposes a signed JET_ERR.

The key comparison for this HRESULT is this: hrRecordNotFound is a failed key lookup; this result describes a row that existed in the cursor lifecycle. The first useful observation is to capture transaction boundaries, cursor position, bookmark, and the session that performed the delete. This it evidence distinguishes failed lookup, lost cursor currency, deleted rows, invalid bookmarks, and prepared-update state.

The ESE objects in play

Diagnostic layercursor currency, bookmarks, prepared updates, and row lifecycle
Typical API surfaceJetMove, JetSeek, JetGetBookmark, JetGotoBookmark, JetPrepareUpdate, JetUpdate, and JetDelete
Code-specific boundarythe cursor refers to a row that was deleted after it became the current record
First corrective directionreseek from a stable key or bookmark and make deletion an expected concurrency outcome

Preparing an update creates cursor state that must be completed or cancelled deliberately., cursor currency can be invalidated by navigation, deletion, rollback, or concurrent changes.

Questions the logs must answer

A useful trace for this HRESULT should preserve the first failing operation and the state of the cursor currency, bookmarks, prepared updates, and row lifecycle.

Log lengths, hashes, IDs, flags, and redacted samples where appropriate.

Response and verification

  1. Freeze the failing request context and record it, 0xC80003F9, the Jet API name, and the current instance/session ownership.
  2. Verify the code-specific precondition: capture transaction boundaries, cursor position, bookmark, and the session that performed the delete.
  3. Apply the narrow correction: reseek from a stable key or bookmark and make deletion an expected concurrency outcome.
  4. Before retrying it, reconcile cursor currency, row existence, bookmark validity, and prepared-update cleanup.
  5. add a regression test that forces the old boundary and proves cleanup leaves no stale handles; then repeat the smallest read-only or disposable test that exercises the corrected precondition.

Developer-facing acceptance test

Build a focused test that reproduces it at the cursor currency, bookmarks, prepared updates, and row lifecycle layer. Record the precondition, execute one API call, and assert the HRESULT plus the resulting handle and transaction state. The corrected it test should change only the decisive condition—the cursor refers to a row that was deleted after it became the current record—and should prove that cleanup is safe if the call still fails.

Distinguishing signals

For this HRESULT, hrRecordNotFound is a failed key lookup; it describes a row that existed in the cursor lifecycle. The following neighboring results belong to the same broad subsystem but mark different boundaries:

hrRecordClusteredChangedan update attempted to change a clustered key in a way the engine cannot apply in place
hrRecordNotFounda seek or lookup found no row matching the constructed key or bookmark criteria
hrNoCurrentRecordthe cursor is before-first, after-last, on a deleted row, or otherwise not positioned on a record

Keep it in the incident record; replacing it with “database error” hides whether the next step is handle renewal, schema correction, lock reconciliation, or file preservation.

Actions that can hide or worsen the problem

Technical references


Looking for a different code? Search another status or error code.

Exit mobile version