Search Results for

# Error Code Reference

Every export in `FEX.Core.dll` returns an `int32`. Zero (`RESULT_OK`) is success; negative values are errors; some functions (notably `OpenImage`) return positive values that are not errors. The constants below are mirrored in `sdk/examples/csharp/NativeMethods.cs` so you can use them verbatim from C#.

- Quick reference
- Detailed catalog
- Common scenarios
- Handling errors in C#

## Quick reference

Code | Constant | Category | Meaning
--- | --- | --- | ---
0 | `RESULT_OK` | Success | Operation completed
-1 | `RESULT_ERROR` | General | Unhandled exception or unspecified failure
-2 | `RESULT_BUFFERTOSMALL` | Memory | Caller-allocated buffer too small (legacy)
-3 | `RESULT_NOFILEFOUND` | Filesystem | File not found on disk
-4 | `RESULT_IMAGENOTSUPPORTED` | Image | Image format not recognised
-5 | `RESULT_IMAGEIDNOTFOUND` | Image | Image ID not in session pool
-6 | `RESULT_COULDNOTOPENIMAGE` | Image | Image open failed
-7 | `RESULT_FILEINDEXNOTFOUND` | Filesystem | File index out of range
-8 | `RESULT_FILENOSIZE` | Filesystem | File has zero data
-9 | `RESULT_INCOMPLETEREAD` | I/O | EOF reached early
-10 | `RESULT_NOSTREAM` | I/O | Stream handle invalid
-11 | `RESULT_NOFILESYSTEM` | Filesystem | Image has no filesystem
-12 | `RESULT_IMAGENODATA` | Image | Image contains no data
-13 | `RESULT_CORRUPTED_IMAGE` | Image | Image structure unreadable
-14 | `RESULT_ENCRYPTED_DATA` | Crypto | Data encrypted, cannot read
-15 | `RESULT_INVALID_JSON` | Input | JSON input malformed
-16 | `RESULT_ACCESS_DENIED` | I/O | Permission denied
-17 | `RESULT_OUT_OF_MEMORY` | Memory | Allocation failed
-18 | `RESULT_INVALID_PARAMETERS` | Input | Parameter out of valid range
-19 | `RESULT_UNSUPPORTED_FILESYSTEM` | Filesystem | Filesystem type not supported
-20 | `RESULT_INVALIDKEY` | License | Invalid or missing license key
-21 | `RESULT_INVALID_UTF8` | Input | Invalid UTF-8 encoding
-22 | `RESULT_PATH_TRAVERSAL` | Security | Path traversal attempt rejected
-23 | `RESULT_BUFFER_OVERFLOW` | Memory | Size calculation overflow
-24 | `RESULT_CORRUPTED_FILESYSTEM` | Filesystem | Filesystem metadata corrupted
-25 | `RESULT_PLUGIN_NOT_INITIALIZED` | Plugin | Plugin system not initialised
-26 | `RESULT_PLUGIN_NOT_FOUND` | Plugin | Named plugin not found
-27 | `RESULT_PLUGIN_ABORTED` | Plugin | Plugin aborted by user
-28 | `RESULT_PLUGIN_PROCESS_FAILED` | Plugin | Plugin processing failed
-29 | `RESULT_PLUGIN_NO_MATCH` | Plugin | Plugin found no matching data
-30 | `RESULT_INVALID_HANDLE` | Stream | Stream handle invalid or already released
-31 | `RESULT_PASSWORD_REQUIRED` | Crypto | Encrypted image needs a password
-32 | `RESULT_PASSWORD_INCORRECT` | Crypto | Password supplied but did not unlock

## Detailed catalog

### `RESULT_OK` (0)

Operation completed successfully. For `OpenImage` a positive integer ID is returned instead — those should be treated as success too. Always compare against the named constant, not the literal `0`.

### `RESULT_ERROR` (-1)

A general / unhandled failure. The DLL caught an exception that doesn't map to one of the more specific codes. Log the operation, the inputs, and the SDK version, and contact support if it persists.

### `RESULT_BUFFERTOSMALL` (-2)

Returned only by legacy V1-style entry points that take a caller-allocated buffer (e.g. `GetVersion`, `ReadImageData`, `ReadFileData`). The current V2 buffer pattern allocates inside the DLL and cannot return this code.

If you see it from `ReadFileData` or `ReadImageData`, increase the buffer size and retry. For everything else, switch to the V2 entry point that returns `(out IntPtr Buffer, out uint BufferSize)`.

### `RESULT_NOFILEFOUND` (-3)

The path passed to a function that operates on a host-filesystem file (e.g. `GetImageInfoByFilenameAsJSON`, `GetFilePropertiesFromPathAsJSON`) did not exist. Verify the absolute path and that the process has read permission.

### `RESULT_IMAGENOTSUPPORTED` (-4)

The DLL recognised that the file is some kind of image but does not have a driver for it. Check the supported-formats matrix in `docs/FEXCore_Filesystem_Catalog.xlsx` and the SDK release notes. Multi-part images sometimes return this when only a non-first segment is passed — always supply the first segment (`.E01`, `.001`, etc.).

### `RESULT_IMAGEIDNOTFOUND` (-5)

You passed an `ImageID` that has not been issued by `OpenImage`, or that has already been closed by `CloseImage` / `CloseAllImages`. IDs are positive integers; `0` and negatives are never valid.

### `RESULT_COULDNOTOPENIMAGE` (-6)

`OpenImage` failed for a non-encryption reason: the file is corrupt, the header is unrecognised, a required segment is missing, or the file could not be locked for read. Use `GetImageInfoByFilenameAsJSON` first to surface format-specific diagnostics.

### `RESULT_FILEINDEXNOTFOUND` (-7)

The `FileIndex` you passed is not a valid index into the filesystem record array for that image. Indices are zero-based and bounded by the `FileCount` returned from `GetFileSystemRecords_V2`. Always re-fetch the records after `ReadFileSystem` if you intend to index into them.

### `RESULT_FILENOSIZE` (-8)

The file exists but has no data — typical for system entries, free-space markers, partition root nodes, and zero-byte files. Skip the read; the record is still valid metadata.

### `RESULT_INCOMPLETEREAD` (-9)

`ReadFileData` or `ReadImageData` reached EOF before the requested length. The `bytesRead` output will hold what was actually returned. This is normal near the end of a file — treat it as success and stop reading.

### `RESULT_NOSTREAM` (-10)

The handle-based streaming API (`RequestFileStream` / `ReadFileStream` / `ReleaseFileStream`) was called with a handle that has already been released, or a stream could not be allocated. Re-acquire via `RequestFileStream`.

### `RESULT_NOFILESYSTEM` (-11)

The image opened successfully but no filesystem was detected — typical for encrypted unmounted volumes, raw memory dumps, or single-partition images where the filesystem signature didn't match a known driver. For encrypted volumes, supply a password or recovery key via the `OpenImage` options JSON (see v2-api.md → OpenImage).

### `RESULT_IMAGENODATA` (-12)

The image structure is intact but contains no readable data — for example, an empty AFF4 container or a logical evidence file with no entries.

### `RESULT_CORRUPTED_IMAGE` (-13)

A required structural element (segment header, hash table, partition table) is unreadable. Verify the file with the format vendor's tooling (EnCase / FTK Imager / etc.) before opening a support case.

### `RESULT_ENCRYPTED_DATA` (-14)

A specific data range is encrypted and the SDK has no key for it. Most commonly seen on partial-decrypt scenarios; for whole-volume encryption you will see `-31` / `-32` instead.

### `RESULT_INVALID_JSON` (-15)

A JSON input parameter (e.g. the `optionsString` to `OpenImage`, or the spec JSON to `CreatePropertySpecsFromJSON`) failed to parse. Validate the JSON locally and check for required fields. The DLL is strict about UTF-8 — no BOMs, no smart quotes from copy-paste.

### `RESULT_ACCESS_DENIED` (-16)

OS-level permission denied. Check that the current process has read access to the image file and that no other process is holding an exclusive lock.

### `RESULT_OUT_OF_MEMORY` (-17)

Allocation failed. For very large images consider the V3 column-windowed API (v3-api.md) instead of `GetFileSystemRecords_V2`.

### `RESULT_INVALID_PARAMETERS` (-18)

A numeric or pointer parameter was outside the function's allowed range. The most common case is `GetFileSystemRecordsCustom_V3` with a `PropertyCount` that is `<= 0` or `> 100`, or a `StartRecord` past the end of the dataset.

### `RESULT_UNSUPPORTED_FILESYSTEM` (-19)

The image opened and a filesystem signature was identified, but the SDK does not have a driver for that filesystem type. Check the support matrix and consider opening a feature request.

### `RESULT_INVALIDKEY` (-20)

The license key passed to `InitLibrary` is missing, malformed, or rejected by the verifier. Set `FEX_LICENSE_KEY` in the environment, or pass the GetData-issued key string directly. See License Keys for installation steps. Contact `sales@getdata.com` for evaluation keys.

### `RESULT_INVALID_UTF8` (-21)

A string parameter was not valid UTF-8 — typically a Windows code-page filename that wasn't transcoded before being passed in. In C# use the `[MarshalAs(UnmanagedType.LPStr)]` attribute on string parameters and ensure the original `string` was constructed correctly (avoid raw byte arrays from non-UTF-8 sources).

### `RESULT_PATH_TRAVERSAL` (-22)

A path-handling export rejected the input because it contained `..` segments or other traversal indicators. The check is a defence against malicious input; supply a normalised absolute path.

### `RESULT_BUFFER_OVERFLOW` (-23)

A size calculation inside the DLL would overflow `uint32` — typical for extremely large filesystems serialised as a single JSON document. Switch to V3 windowed extraction (`GetFileSystemRecordsCustom_V3` with a page size like 100,000) to bypass the limit.

### `RESULT_CORRUPTED_FILESYSTEM` (-24)

Filesystem metadata is unreadable. Some drivers are tolerant of damage and will continue with partial results; this code is returned when even the root structures are unparseable.

### `RESULT_PLUGIN_NOT_INITIALIZED` (-25) / `RESULT_PLUGIN_NOT_FOUND` (-26) / `RESULT_PLUGIN_ABORTED` (-27) / `RESULT_PLUGIN_PROCESS_FAILED` (-28) / `RESULT_PLUGIN_NO_MATCH` (-29)

Reserved for the plugin / driver pipeline used by Forensic Explorer. The public SDK surface does not currently expose plugin invocations directly, so customers will rarely see these codes. If you do, treat as `RESULT_ERROR` and contact support.

### `RESULT_INVALID_HANDLE` (-30)

The stream handle passed to `ReadFileStream` or `ReleaseFileStream` is not in the active pool — either it was never issued, or it has already been released. Always pair `RequestFileStream` with exactly one `ReleaseFileStream`.

### `RESULT_PASSWORD_REQUIRED` (-31)

The image is encrypted (BitLocker, FileVault, encrypted EnCase, encrypted DMG, etc.) and `OpenImage` was called without a password. Supply one via the `optionsString` JSON:

    {
      "Password": "MyVolumePassword"
    }

For BitLocker recovery-key files, pass the path to the `.bek` file; the DLL will detect the file format. The FexViewer manifest format (see the example's README) supports a `passwords` array that mixes literal passwords and key-file paths and is tried in order.

### `RESULT_PASSWORD_INCORRECT` (-32)

A password was supplied but the volume rejected it. Check the password, re-export recovery keys if you have them, and verify you're using the right key file for the right volume in multi-volume cases.

## Common scenarios

### "License key invalid" on every call

`InitLibrary` succeeded but you're seeing `RESULT_INVALIDKEY` on subsequent calls. The license probably hasn't been initialised in the current process — `InitLibrary` sets per-process state, so each new process must call it once before any other export. The FexViewer example does this in `Program.cs` immediately after argument parsing.

### Image opens but `ReadFileSystem` returns `-11`

The image is encrypted at the volume level (BitLocker, APFS-encrypted, etc.). Close the image and re-open with a password in `optionsString`.

### `RESULT_PASSWORD_INCORRECT` only on a multi-segment image

Multi-segment images like `*.E01 / *.E02 / *.E03` are detected by the first segment alone; you only pass `disk.E01` to `OpenImage`. If companion files are missing the DLL may fail later with a generic `RESULT_COULDNOTOPENIMAGE` — but for encrypted multi-segment images, all segments must be present in the same directory before the password attempt, otherwise unlock can spuriously fail.

### `RESULT_BUFFER_OVERFLOW` on a million-record image

`GetFileSystemRecords_V2` materialises every record at once. For datasets where that's too large, use `GetFileSystemRecordsCustom_V3` with pagination — see v3-api.md for an end-to-end C# example.

### "DLL not found" / `DllNotFoundException`

Not a result code — this is a host-OS loader error. `FEX.Core.dll` and its runtime dependencies (`libcrypto-1_1-x64.dll`, `bzip2.dll`, plus optional `sk4d.dll` and `libaff4.dll` if you build with those) must sit beside your executable, in `System32`, or on the search path.

The FexViewer csproj copies all required runtime DLLs to its `bin/` on each build — see `sdk/examples/csharp/FexViewer.csproj` for the pattern.

## Handling errors in C#

The FexViewer example wraps DLL calls in a single helper that throws a `FexCoreException` with the result code. The pattern below is a reasonable starting point.

    public sealed class FexCoreException : Exception
    {
        public int ErrorCode { get; }

        public FexCoreException(string message, int errorCode)
            : base(message) { ErrorCode = errorCode; }
    }

    private static string ErrorMessage(int code) => code switch
    {
        NativeMethods.RESULT_OK                  => "OK",
        NativeMethods.RESULT_ERROR               => "General error",
        NativeMethods.RESULT_IMAGENOTSUPPORTED   => "Image format not supported",
        NativeMethods.RESULT_IMAGEIDNOTFOUND     => "Image ID not found",
        NativeMethods.RESULT_COULDNOTOPENIMAGE   => "Could not open image",
        NativeMethods.RESULT_FILEINDEXNOTFOUND   => "File index not found",
        NativeMethods.RESULT_INVALIDKEY          => "Invalid license key",
        NativeMethods.RESULT_INVALID_UTF8        => "Invalid UTF-8 input",
        NativeMethods.RESULT_PATH_TRAVERSAL      => "Path traversal rejected",
        NativeMethods.RESULT_INVALID_HANDLE      => "Invalid handle",
        NativeMethods.RESULT_PASSWORD_REQUIRED   => "Image is encrypted; supply a password",
        NativeMethods.RESULT_PASSWORD_INCORRECT  => "Password did not unlock the image",
        _ => $"Unknown error code: {code}"
    };

    private static void Check(int rc, string operation)
    {
        if (rc != NativeMethods.RESULT_OK)
            throw new FexCoreException($"{operation}: {ErrorMessage(rc)}", rc);
    }

    // Usage
    Check(NativeMethods.ReadFileSystem(imageId, out _), "ReadFileSystem");

Two cases warrant their own handling rather than a generic exception:

- `RESULT_PASSWORD_REQUIRED` / `RESULT_PASSWORD_INCORRECT` — these are user-recoverable. Prompt for a different password and retry rather than surfacing a stack trace.
- `RESULT_INCOMPLETEREAD` — not really an error during streaming reads. Treat as "EOF, stop here" and use the `bytesRead` you already have.