> ## Documentation Index
> Fetch the complete documentation index at: https://docs.threataware.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Codes

> Reference for error codes and error messages surfaced across Protect — sync, actions, integration auth, API

This page is the catalogue of error codes and named error states you'll encounter across Protect. For symptom-driven debugging see [Troubleshooting](/reference/troubleshooting); this page is the structured reference of every error string the product can show.

<Info>
  The error strings on this page reflect what Protect surfaces in the UI. Exact vendor-side strings can vary by integration and release.
</Info>

## API HTTP status codes

The [ThreatAware API](/api-reference/introduction) returns a JSON envelope of the form `{"Success": false, "StatusCode": <code>, "Message": "<text>"}` on errors. The HTTP status, the `StatusCode` field, and the human `Message` are all surfaced verbatim in API client integrations.

Live-captured response shapes:

| HTTP status   | Trigger                                                    | Response body                                                               |
| ------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------- |
| `200`         | Successful request                                         | Request payload                                                             |
| `400`         | Invalid API key value (e.g. `X-ThreatAware-ApiKey: BOGUS`) | `{"Success":false,"StatusCode":400,"Message":"Unexpected error occurred."}` |
| `400`         | Unknown path under `/public-api/v1/`                       | `{"Success":false,"StatusCode":400,"Message":"Unexpected error occurred."}` |
| `401`         | No `X-ThreatAware-ApiKey` header                           | `{"Success":false,"StatusCode":401,"Message":"No key was provided."}`       |
| `403`         | Token lacks scope for resource                             | Body varies; check [Role Permissions](/reference/role-permissions)          |
| `404`         | Resource ID not found (e.g. unknown device UUID)           | Standard 404                                                                |
| `429`         | Rate limit exceeded                                        | Standard 429 — implement exponential backoff                                |
| `500`         | Internal server error                                      | Retry; if persistent, contact support                                       |
| `502` / `503` | Upstream / temporary outage                                | Retry with backoff                                                          |

<Warning>
  The `400` vs `401` split is **header presence** versus **header value**. Send the header with garbage and you get `400 / "Unexpected error occurred."`; omit the header entirely and you get `401 / "No key was provided."`. Library defaults that strip empty headers will trip this distinction.
</Warning>

See [API Reference → Response Codes](/api-reference/introduction) for the canonical list and rate-limit handling guidance.

## Sync errors (Integrations)

Integration sync state is surfaced on each integration card in [Settings → Connections](/settings/integrations) (the URL is `/settings/connections`). The connected state on a healthy card is the literal label `CONNECTED`; the Modify button beneath it opens a dialog with `Enable Multi-Tenancy`, `Reauthorise`, and `Disconnect` sections.

Categories of sync error (structural — exact per-integration sync error strings vary by vendor):

| Category                      | Typical surface                                                       | Resolution path                                                                                                                                    |
| ----------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Auth expired**              | Card last-sync timestamp goes stale; vendor returns 401 on next cycle | [Settings → Connections](/settings/integrations) → card → Modify → Reauthorise → re-enter credentials or re-run OAuth                              |
| **Auth revoked**              | Same as auth expired; vendor-side consent withdrawn                   | Re-grant consent on the vendor side, then Modify → Reauthorise                                                                                     |
| **Insufficient scopes**       | Specific Vitals rows show stale data while the card stays CONNECTED   | Add missing scopes vendor-side; for Microsoft see the [Graph permissions guide](/connection-guides/microsoft-graphapi-required-permissions)        |
| **Rate-limited by vendor**    | Card stays CONNECTED but "Last synced" timestamps lengthen            | Wait for the next cycle; reduce sync frequency if persistent                                                                                       |
| **Vendor outage**             | Card last-sync stale, vendor returns 5xx                              | Check vendor status page; the next successful sync clears the state                                                                                |
| **PowerShell Relay offline**  | On-prem integrations only                                             | RDP to relay server, verify the scheduled task and event log — see [PowerShell Relay troubleshooting](/reference/troubleshooting#powershell-relay) |
| **TLS / certificate failure** | PowerShell Relay integrations                                         | Install a valid certificate, or enable Bypass Certificate Check on the integration                                                                 |

## Action errors

Errors that surface in the **Automation Log** when an Action's automation fires.

| Category                          | Surface                                                 | Resolution path                                                                                                                         |
| --------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **Email delivery failed**         | Automation Log row → status `Failed`                    | Check recipient address validity; verify the recipient hasn't filtered `noreply@threataware.com`                                        |
| **Webhook timeout**               | Automation Log row → status `Failed`, response code n/a | Endpoint slow or unreachable; verify the URL is reachable from ThreatAware egress; widen the destination timeout                        |
| **Webhook 4xx response**          | Automation Log → response code visible                  | Endpoint rejected the payload — see [Webhook Payload Reference](/reference/webhook-payload) for the expected shape                      |
| **Webhook 5xx response**          | Automation Log → response code visible                  | Destination server error; the action will retry — see [Webhook Payload Reference → Retries](/reference/webhook-payload#retry-behaviour) |
| **Ticket creation failed**        | Automation Log → integration-specific error             | Re-test the destination integration (ServiceNow / Halo / Jira); confirm credentials and table/queue permissions                         |
| **Resolution criteria malformed** | Action card warning                                     | Open the Action → fix the criteria query — see [Query Syntax](/reference/query-syntax)                                                  |

<Note>
  The webhook **Test Webhook** control reports the literal toast `Successfully complete` / `The request Successfully completed` even when the destination URL returns a 5xx response (verified live by pointing the test at `https://httpbin.org/status/500`). The Test Webhook flow validates that the request was dispatched, not that the destination accepted it. For end-to-end validation, save the Action, let it fire, and read the Automation Log on the Action detail page.
</Note>

## Integration auth errors

Specific errors during the **Connect** wizard and during re-authentication.

The **Reauthorise** flow on a connected integration is a 4-step wizard (`Step 1 of 4` → `Step 4 of 4`). Step 4 is the credentials form (label set varies by integration — e.g. ServiceNow exposes `Platform URL`, `User ID`, `Password`; the URL field placeholder is `https://dev123456.service-now.com`). The Step 4 button is `Authorise`.

ServiceNow behaviour:

* Submitting invalid credentials via the Reauthorise flow returns a `Credentials saved` confirmation in the dialog, followed by a `Connect ServiceNow / ServiceNow is connecting, changes will appear soon` toast on the connections page.
* **The Authorise step does not synchronously test credentials.** Sync failure for bad credentials surfaces later on the integration card (stale last-sync timestamp) and in the next cycle's audit log entries — not as an immediate wizard error.

| Symptom in wizard                                                          | Likely cause                                                                                                                                     |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Wizard accepts credentials, card stays CONNECTED, last-sync never advances | Wrong credential format (extra whitespace, wrong field, expired secret) or scope missing — vendor-side failure on the first cycle                |
| Wizard accepts credentials, card later returns to a degraded state         | Same as above; the Reauthorise flow validates input format, not vendor-side acceptance                                                           |
| OAuth consent screen rejects                                               | Insufficient privileges to consent (need Global Admin / equivalent); see [Onboarding](/onboarding#microsoft-integrations-need-global-admin-once) |
| Connection succeeds, no data after first sync                              | Service account lacks read scopes against the resources in question                                                                              |
| PowerShell Relay `401 Unauthorised`                                        | Wrong credentials, or the running account lacks permissions on the on-prem tool                                                                  |

## Platform error states

These appear in the UI rather than as numeric codes.

Vitals composite states (per the live device drawer):

| State                                    | Where it appears                                                     | Meaning                                                                                                                                       |
| ---------------------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **Healthy**                              | Vitals row on a device drawer / Vitals grid                          | Control deployed, functioning, and configured correctly                                                                                       |
| **Functioning**                          | Vitals row for non-Required controls (identity / management)         | Control reporting fresh data; no configuration check applied                                                                                  |
| **Not Functioning**                      | Vitals row                                                           | Control is deployed but isn't reporting fresh telemetry — see [Silent Failure](/silent-failure) and [Vitals States](/reference/vitals-states) |
| **Misconfigured**                        | Vitals row                                                           | Control is functioning but at least one configuration check fails — see [Vitals Configuration](/vitals-configuration)                         |
| **Not Deployed**                         | Vitals row                                                           | Control isn't present on this device                                                                                                          |
| **Required**                             | Vitals row qualifier (separate label)                                | The control is in this device's coverage scope — qualifies the state above                                                                    |
| **Detected** / **Not Detected Recently** | Scanners (Lansweeper, Qualys, etc.)                                  | Scanner has / has not seen the device in its recent window                                                                                    |
| **CONNECTED**                            | Integration card in [Settings → Connections](/settings/integrations) | The card's literal badge text for a working integration                                                                                       |

Full state reference: [Vitals States](/reference/vitals-states).

## In-product query parsing

The Device Explorer and Saved View query bars do **not** surface a parse error on malformed input. Invalid queries (e.g. `tags:End-User AND AND OR (((`) silently render `No devices found` rather than raising a syntax error.

This was verified live by submitting the malformed string above to the Device Explorer command bar — the grid emptied to `No devices found` with no error toast or inline message. The same silent-zero behaviour applies to unknown field names (e.g. `os=Windows` returns 0 instead of telling you `=` is not the operator; the correct operator is `:`). See [Query Syntax](/reference/query-syntax) for the verified grammar.

## Cross-references

<CardGroup cols={3}>
  <Card title="Troubleshooting" icon="screwdriver-wrench" href="/reference/troubleshooting">
    Symptom → cause → fix
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    HTTP status codes in detail
  </Card>

  <Card title="Webhook Payload" icon="webhook" href="/reference/webhook-payload">
    Outbound webhook shape and retry behaviour
  </Card>

  <Card title="Vitals States" icon="heart-pulse" href="/reference/vitals-states">
    All Vitals state values
  </Card>

  <Card title="Audit Log Events" icon="clipboard-list" href="/reference/audit-log-events">
    What gets recorded
  </Card>

  <Card title="Support" icon="life-ring" href="mailto:help@threataware.com">
    Escalate persistent errors
  </Card>
</CardGroup>
