# Errors and Status Codes

> Handle 400, 401, 404, 405 and 415 answers of the DocumentProcessing Web API: not registered, validation and token errors, and ServiceRequestException in .NET.

- **Product:** DS Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** DS Server > Document Processing > Errors and Status Codes
- **3181 words**
- **Web URL:** https://docs.textcontrol.com/ds-server/document-processing/errors/
- **LLMs URL:** https://docs.textcontrol.com/ds-server/document-processing/errors/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/ds-server/document-processing/errors/llms-full.txt

---

A request to the DocumentProcessing Web API that fails returns an HTTP status code and, depending on the cause, a message in one of four forms: a JSON string, plain text, a JSON object with validation errors or an empty body. The status codes and messages below were observed on DS Server 5.0.2, together with the causes the endpoint reference lists, so that your application can tell a missing license from an expired token or a malformed request and react to each.

### Status Codes at a Glance

| Status | Meaning | Body |
|---|---|---|
| `200 OK` | The request succeeded | The result, as the endpoint reference describes it |
| `400 Bad Request` | DS Server is not registered, the request is malformed, or the document or a parameter is not valid | A JSON string, plain text or a validation error object |
| `401 Unauthorized` | OAuth is enabled and the access token is missing, invalid or belongs to an expired security profile | Empty |
| `404 Not Found` | The address is not an endpoint | Empty |
| `405 Method Not Allowed` | The endpoint exists, but not for this HTTP method | Empty, with an `Allow` header |
| `415 Unsupported Media Type` | The body is not sent with the content type `application/json` | A JSON problem object |

Only a `200` answer holds a result, so check the status before you decode the response.

### DS Server Is Not Registered

Until DS Server is licensed, every DocumentProcessing endpoint answers `400 Bad Request` with this message:

```text
DS Server is not registered.
```

The Web API creates no trial output and no documents with a watermark: without a license, it creates no documents at all. Register the server with a serial number in the admin portal, as [Licensing](https://docs.textcontrol.com/ds-server/administration/licensing/llms-full.txt) shows. The Document Editor and the Document Viewer show the same message on an unregistered server.

The message comes in two content types, depending on the endpoint:

| Content type | Body | Endpoints |
|---|---|---|
| `application/json` | `"DS Server is not registered."`, a JSON string with quotes | document/convert, document/findandreplace, document/append, document/thumbnails, document/info, document/installedprinters, pdf/create, pdf/metadata, barcodes/create, barcodes/defaulttext, barcodes/istextvalid |
| `text/plain` | `DS Server is not registered.` without quotes | document/merge, pdf/embeddedfiles, pdf/acroforms/fields, barcodes/maximumtextlength, barcodes/minimumtextlength |

Read the body as text and remove the quotes when the content type is JSON, so that one comparison works for both.

DS Server checks the license before it checks the values of the parameters. An unknown barcode type or return format also gets "DS Server is not registered." on an unregistered server, so the errors described in [Errors of the Endpoints](#errors-of-the-endpoints) appear only once the server is registered. Validation errors of the JSON body and of the parameter types come first, as the next section describes.

### Validation Errors

A body or a parameter that can't be read as the type the endpoint expects is refused with `400` and a problem details object, a JSON object whose `type` points to RFC 9110, before the license check. For example, the convert endpoint expects the document as a JSON string, and a JSON object as its body gives:

```json
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "$": [
      "The JSON value could not be converted to System.String. Path: $ | LineNumber: 0 | BytePositionInLine: 1."
    ]
  },
  "traceId": "00-98bb1d86ed54a2b27c74e70ef8de604f-8ebe2856831ddc90-00"
}
```

`errors` names what could not be read: `$` is the whole body, `$.documentAccessPermissions` a property of the body, and a name without `$`, such as `zoomFactor`, a query parameter. Typical causes:

- **A JSON object where the endpoint expects a string**, or the reverse. The convert, info and thumbnails endpoints and the three PDF reading endpoints take the document as a JSON string alone. The merge, append, find-and-replace, pdf/create and barcodes/create endpoints take a JSON object.
- **A value of the wrong type in the body**, such as a string for a number or a name for an enumeration. For example, `documentAccessPermissions` of pdf/create takes a number, and `"AllowAll"` gives "The JSON value could not be converted".
- **A query parameter that is not a valid number or Boolean**, such as `zoomFactor=abc` or `flattenFormFields=maybe`, which gives "The value 'abc' is not valid.".

Properties of the body that an endpoint doesn't know are ignored without an error. A misspelled property name therefore doesn't fail the request, but its setting has no effect.

### Errors of the Endpoints

Once DS Server is registered, the endpoints check the document and the parameters. The endpoint reference lists these causes of `400 Bad Request`:

| Cause | Endpoints |
|---|---|
| The uploaded document is not valid | document/convert, document/merge, document/findandreplace, document/append, document/thumbnails, document/info, pdf/create, pdf/embeddedfiles, pdf/acroforms/fields |
| No document or data was found in the body | document/merge, document/findandreplace, document/append, document/thumbnails, document/info, pdf/create, pdf/embeddedfiles, barcodes/create |
| The image format is not supported | document/thumbnails |
| The page numbers are not valid | document/thumbnails |
| No metadata was found in the PDF document | pdf/metadata |
| No form fields were found in the PDF document | pdf/acroforms/fields |
| The barcode type is not valid | barcodes/defaulttext, barcodes/maximumtextlength, barcodes/minimumtextlength, barcodes/istextvalid |

The pages of the endpoints under [DocumentProcessing](https://docs.textcontrol.com/ds-server/reference/web-api/documentprocessing/llms-full.txt) give the cause for each endpoint. For pdf/metadata and pdf/acroforms/fields, a `400` can mean that the PDF has no metadata or no form fields, not that the request is wrong.

### Access Token Errors

When OAuth is enabled in the admin portal, DS Server checks the access token of every request and answers `401 Unauthorized` with an empty body:

| Request | Answer |
|---|---|
| No token | `401`, with the header `WWW-Authenticate: Bearer` |
| An unknown or invalid token | `401`, without a `WWW-Authenticate` header |
| A token of a security profile whose expiry date has passed | `401` |

Request a new token and send the request again. If the new token is refused as well, check the expiry date of the security profile in the admin portal, as [Creating Security Profiles](https://docs.textcontrol.com/ds-server/administration/security-profiles/llms-full.txt) shows: DS Server still issues tokens for an expired profile, but accepts none of them.

When OAuth is disabled, which is the default of a new installation, DS Server checks no token: a request with an invalid token or without one reaches the endpoint. [Enable OAuth](https://docs.textcontrol.com/ds-server/administration/oauth/llms-full.txt) switches the check on.

The token request itself, `POST /oauth/token`, answers errors with `400` and a JSON object with `error` and `error_description`:

| `error` | `error_description` | Cause |
|---|---|---|
| `invalid_request` | "Missing authorization header." | The client ID and secret were sent as form fields only, without the Basic `Authorization` header |
| `invalid_client` | "Invalid client ID." | No security profile has this client ID |
| `invalid_client` | "Invalid client secret." | The client secret is wrong |
| `unsupported_grant_type` | "This security profile does not allow the specified grant type. (client\_credentials)" | The security profile doesn't allow the client credentials grant type |
| `invalid_grant` | "Invalid refresh token." | The refresh token is unknown or no longer valid |

A token request with a JSON body instead of form data gets `405 Method Not Allowed`, with a JSON problem object as its body. [Authentication](https://docs.textcontrol.com/ds-server/document-processing/authentication/llms-full.txt) shows the requests that work.

### Wrong Address, Method or Content Type

- **`404 Not Found`, empty body.** The path is not an endpoint. Check the spelling and the service URL: when DS Server runs as an application below an IIS site, the service URL includes the name of the application. The changelog of version 3.3.0, for example, names the printer endpoint `document/printers`, which answers `404`; the endpoint is `document/installedprinters`.
- **`405 Method Not Allowed`, empty body.** The path exists for another HTTP method. The `Allow` header names it, such as `Allow: POST` for a `GET` request to document/convert.
- **`415 Unsupported Media Type`.** A request with a body was sent without the header `Content-Type: application/json`, or with another content type such as `text/plain`. The body is a JSON object with `"title": "Unsupported Media Type"` and `"status": 415`.

### Handle Errors in .NET

The package `TXTextControl.DocumentServices.DocumentProcessing` turns a refused request into a `ServiceRequestException`. Its `StatusCode` property holds the HTTP status as an `HttpStatusCode`, and its message contains the method, the endpoint and the answer of DS Server:

```text
POST request to document/convert failed: DS Server is not registered. (Status code 400 / BadRequest)
POST request to document/convert failed for unknown reasons. Status code 401 / Unauthorized.
```

The constructor of `DocumentProcessing` requests the access token right away. When that fails, because the credentials are wrong, the profile doesn't allow the grant type or DS Server can't be reached, the constructor throws an `AggregateException` whose inner exception says why, such as:

```text
OAuth access token request failed. error: "invalid_client", error_description: "Invalid client secret."
```

The following console application handles each case:

```csharp
using System.Net;
using TXTextControl.DocumentServices.DocumentProcessing;
using TXTextControl.DocumentServices.DocumentProcessing.OAuth;

var oauthSettings = new OAuthSettings("<client ID>", "<client secret>");
byte[] document = File.ReadAllBytes("document.docx");

try
{
    // The constructor requests the access token
    var documentProcessing = new DocumentProcessing("http://localhost:5000", oauthSettings);

    byte[] pdf = await documentProcessing.Convert(document, ReturnFormat.PDF);
    File.WriteAllBytes("document.pdf", pdf);
}
catch (ServiceRequestException exception) when (exception.StatusCode == HttpStatusCode.Unauthorized)
{
    Console.WriteLine("The access token was refused.");
}
catch (ServiceRequestException exception)
{
    // For example 400: "DS Server is not registered."
    Console.WriteLine($"{(int)exception.StatusCode}: {exception.Message}");
}
catch (AggregateException exception)
{
    // No access token: wrong credentials, grant type not allowed or server not reachable
    Console.WriteLine(exception.InnerException?.Message);
}
```

The code works as follows:

- The first `catch` block handles a refused token, the second every other status code of the Web API, with the message of DS Server.
- The third `catch` block handles a failed token request of the constructor. Its inner exception holds the OAuth error, or the connection error when the service URL is wrong.

`InstalledPrinters` is the exception: in version 5.0.0 of the package, it throws a plain `Exception` whose message starts with "ServiceRequestException when trying to parse response content of endpoint", followed by the message of the refused request, and which has no status code.

In version 5.0.0 of the package, an instance created with `DocumentProcessing.CreateInstanceAsync` requests a token but doesn't send it with its requests. With OAuth enabled, every call of such an instance fails with `401`. Create the instance with the constructor, as the code above does.

### Related Pages

- [Authentication](https://docs.textcontrol.com/ds-server/document-processing/authentication/llms-full.txt): request and send access tokens.
- [Licensing](https://docs.textcontrol.com/ds-server/administration/licensing/llms-full.txt): register DS Server with a serial number.
- [Enable OAuth](https://docs.textcontrol.com/ds-server/administration/oauth/llms-full.txt): switch the token check on or off.
- [DocumentProcessing](https://docs.textcontrol.com/ds-server/reference/web-api/documentprocessing/llms-full.txt): the endpoints and the errors each one lists.

---

## Nearby

- **Previous:** [Barcodes](https://docs.textcontrol.com/ds-server/document-processing/barcodes/llms-full.txt)
- **Next:** [Plugins](https://docs.textcontrol.com/ds-server/plugins/llms-full.txt)
