# Errors

Location: [gRPC API](https://developer.m-files.com/APIs/gRPC-API/index.md) > [Runtime conventions](https://developer.m-files.com/APIs/gRPC-API/index.md#runtime)

HTML version: https://developer.m-files.com/APIs/gRPC-API/runtime/errors/

M-Files Server reports every failure of its own with one of two gRPC status codes:

| Status | Meaning | Details |
|---|---|---|
| `UNAUTHENTICATED` | The session is missing, unknown, expired or logged out. | A fixed message ("The current session with M-Files Server is no longer valid..."). No error trailers. Log in again; see [Authentication and sessions](https://developer.m-files.com/APIs/gRPC-API/runtime/authentication/index.md#when-a-call-answers-unauthenticated). |
| `UNKNOWN` | Any other M-Files error, including a failed login. | The status message is the top-level error text. The trailers carry the full M-Files error. |

Other status codes come from the gRPC layer, not from M-Files logic:

| Status | Typical cause |
|---|---|
| `RESOURCE_EXHAUSTED` | A message over a size limit (`SERVER: Received message larger than max` or `CLIENT: ...`). See [Connecting](https://developer.m-files.com/APIs/gRPC-API/runtime/connecting/index.md#message-size-limits). |
| `UNIMPLEMENTED` | The method does not exist on this server, for example a method newer than the server version. |
| `UNAVAILABLE` | No connection: address, port, firewall or TLS problem. |
| `DEADLINE_EXCEEDED`, `CANCELLED` | Set by the client. The server may still complete the call; see [Call metadata](https://developer.m-files.com/APIs/gRPC-API/runtime/call-metadata/index.md#deadlines-and-cancellation). |

## The error trailers

A call that fails with `UNKNOWN` has two trailers:

| Trailer | Content |
|---|---|
| `mfiles-error-serialized-bin` | A serialized [RPCErrorInfoArray](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.RPCErrorInfoArray/index.md): the M-Files error stack. |
| `mfiles-error-text-bin` | The same stack as UTF-8 text, one line per entry. For logs. |

Each [RPCErrorInfo](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.RPCErrorInfo/index.md) has `error_code` (an HRESULT as a signed 32-bit
integer), `description` (extra detail, often empty), and `file` and `line` (the server source
location). The entries run from the original cause (first) to the top-level error (last); the
status message describes the last one. The same code usually repeats as the error passes up through
the server. Example for an unknown vault GUID at login:

| Index | `error_code` | Meaning | `description` |
|---|---|---|---|
| 0 | `0x80040120` | Free-text detail | `Vault ID: {11111111-2222-3333-4444-555555555555}` |
| 1, 2 | `0x80040020` | `E_MFILES_UNKNOWN_VAULT` | |

Status message: `The specified document vault does not exist.` followed by the Vault ID line.

When the stack is too large for the trailer limit, the server drops entries from the middle and
shortens long texts; the first and the last entries are kept.

**Which code to act on.** Test whether a code you handle appears anywhere in the stack. The last
entry is the top-level error and the most stable choice; the first one names the original cause,
which is sometimes more specific (for "access denied", the first entry says whether vault-level or
object-level rights were missing) and sometimes only a free-text carrier (`0x80040120`). Do not
parse the message text: it can change between versions. A missing permission does not always
produce an error: [Permissions](https://developer.m-files.com/APIs/gRPC-API/concepts/permissions/index.md#what-access-denied-looks-like) shows
when the server answers "Not found." or leaves items out instead.

The text trailer and `file`/`line` are diagnostics that include server source file names and the
server version. Log them; do not show them to end users.

### Decoding in Python

The samples' helper decodes the stack into a list of entries and their unsigned codes:

```python
self.long_message: str = trailers.get(ERROR_TEXT_KEY, b"").decode("utf-8", "replace")
self.stack = list(structs_pb2.RPCErrorInfoArray.FromString(
    trailers.get(ERROR_STACK_KEY, b"")).value)
self.codes = [entry.error_code & 0xFFFFFFFF for entry in self.stack]  # cause first
# The top-level error, skipping entries that only pass the error on.
self.hresult: Optional[int] = next(
    (code for code in reversed(self.codes) if code != E_PASS_THROUGH),
    self.codes[-1] if self.codes else None)
```

*Source: [python/mfiles_client.py](https://developer.m-files.com/APIs/gRPC-API/downloads/samples/python/mfiles_client.py)*

A code is often written as unsigned hex (`0x800407E4`) and sometimes as a signed integer
(`-2147219484`); `code & 0xFFFFFFFF` converts the signed value to the unsigned one. The
[error handling guide](https://developer.m-files.com/APIs/gRPC-API/guides/errors/index.md) shows the same in C# and Go.

## Common error codes

Observed against a server unless marked "code only". The message is the English status message.

| Name | HRESULT | Signed | Message | When | What to do |
|---|---|---|---|---|---|
| Invalid session | `0x8004001B` | -2147221477 | The current session with M-Files Server is no longer valid... | Session missing, expired or logged out. Status `UNAUTHENTICATED`, no trailers. | Log in again with `LogIn`. |
| `E_MFILES_AUTHENTICATION_FAILED` | `0x8004001A` | -2147221478 | Authentication failed. | Wrong password, unknown user, anonymous login not allowed, login temporarily blocked. | Ask for new credentials; do not retry in a loop. |
| `E_MFILES_LOGIN_REQUIRED` | `0x80040043` | -2147221437 | Login required. | A vault method called with a server-level session. | Log in to the vault (`LogInWithSession`). |
| `E_MFILES_UNKNOWN_VAULT` | `0x80040020` | -2147221472 | The specified document vault does not exist. | Login with a vault GUID the server does not have. | Check the GUID; list vaults with `GetVaults`. |
| `E_MFILES_INVALID_VAULT_GUID_X_DESC` | `0x80040034` | -2147221452 | Invalid Vault GUID: "..." | `vault_guid` is empty or not a GUID. | Send a GUID; all zeros for server level. |
| `E_MFILES_VAULT_OFFLINE` | `0x80040061` | -2147221407 | (code only) | The vault is offline for maintenance. | Retry later. |
| `E_MFILES_ACCESS_DENIED` | `0x800407E4` | -2147219484 | Access denied. You do not have the access rights required by this operation. | An operation the user's rights do not allow, or an object the user cannot see. | Report to the user; do not retry. |
| `E_MFILES_LACKING_VAULT_LEVEL_ACCESS_RIGHTS` | `0x800400A9` | -2147221335 | (first entry under access denied) | The user lacks a vault-level right, for example for administrative methods. | As access denied. |
| `E_MFILES_LACKING_DOC_LEVEL_ACCESS_RIGHTS` | `0x800400AA` | -2147221334 | Access denied. You do not have sufficient access rights to the object. (first entry) | The object's permissions do not allow the operation. | As access denied. |
| `E_MFILES_NOT_FOUND` | `0x8004000B` | -2147221493 | Not found. | An object ID that does not exist or was destroyed; a download ID that is not open. | Check the ID; for downloads, start again. |
| `E_MFILES_NOT_FOUND_X` | `0x800408A4` | -2147219292 | Not found. 9999 | An unknown item ID, such as an object type ID; the description names it. | Check the ID. |
| `E_MFILES_DOCUMENT_REMOVED` | `0x8004006D` | -2147221395 | The object has been removed. (ID: 529) | Changing a deleted object. | Undelete it first, or skip it. |
| `E_MFILES_CHECKED_OUT_TO_ANOTHER_USER` | `0x80040019` | -2147221479 | The object is checked out to another user. | Checking out or changing an object someone else has checked out. | Retry later or ask the user to check it in. |
| `E_MFILES_NOT_CHECKED_OUT` | `0x800400B2` | -2147221326 | The object is not checked out. | Changing a checked-in object without checking it out, and without the method's option to modify a checked-in object. | Check out first, or use that option. |
| `E_MFILES_NEWER_VERSION_EXISTS` | `0x800400BB` | -2147221317 | There is a newer version of this object on the server. | A change based on an old version, with the request's "fail if a newer version exists" option set. | Read the latest version, merge, try again. |
| `E_MFILES_ATTEMPT_TO_CHANGE_CLASS` | `0x80040015` | -2147221483 | You cannot change the class of the object using this method. | The class property (100) sent to a method that does not change the class; observed with `SetProperties` even when the value was the object's current class. | Leave the class out. |
| `E_MFILES_WRONG_DATATYPE_FOR_PROPERTYDEF_X_DESC` | `0x8004009A` | -2147221350 | Wrong data type for property definition "Name or title". | A typed value whose type does not match the property definition. | Use the property definition's data type. |
| `E_MFILES_UNABLE_TO_ACCESS_PROPERTYDEF` | `0x8004097E` | -2147219074 | You can't get access to the property "987654". Make sure that the property definition exists and you have access to it. | A property definition ID that does not exist or is hidden from the user. | Check the ID. |
| `E_INVALIDARG` | `0x80070057` | -2147024809 | The parameter is incorrect. | A malformed request: a wrong-length binary header, a "latest version" reference where a specific version is required, a download block over 4 MiB, and many more. Look for a description in the stack. | Fix the request. |
| `E_NOTIMPL` | `0x80004001` | -2147467263 | Not implemented. | A published method whose feature is not enabled on this server, such as the stateless upload methods, or a method that serves only the HTTP gateway, such as `DownloadFile`. | Use the equivalent the method's reference names; for files see [Files](https://developer.m-files.com/APIs/gRPC-API/runtime/files/index.md). |
| `E_MFILES_CALL_REJECTED` | `0x80040044` | -2147221436 | The server is too busy to process the request at this time. (code only) | A call sent with `CALL_IMPORTANCE_CAN_BE_REJECTED` while the server is busy. | Retry later. |
