---
updatedAt: 2026-09-25T21:22:00.000Z
agentTools:
  projectIndex: https://developer.alloy.com/public/llms.txt
---

# Policy Design for Service Failures

Alloy's Workflow and Journey builder includes several features specifically designed to improve resiliency at the policy layer. Properly configuring these features allows Alloy to deliver valid decisions even when individual vendor services experience failures. This article covers the available tools in order from least to most interventional: tag-level configuration, workflow-level parsing, journey-level retry orchestration, and full application reruns.

## Error Attributes

Error Attributes are a standard set of boolean attributes that Alloy writes onto a service's response whenever that service fails. They describe why a call failed - a timeout, a rate limit, rejected credentials, a malformed request - so your policy can respond appropriately to different failure scenarios.

Unlike vendor data attributes, Error Attributes are global: the same attributes are available on every service in your Workflow, and you can reference them in tag thresholds exactly like any other attribute.

| Attribute                     | Selector                                     | Indicates                                                      |
| ----------------------------- | -------------------------------------------- | -------------------------------------------------------------- |
| **Any Error Occurred**        | `error_attributes.has_errors`                | Any error occurred while processing the request.               |
| **Has Retryable Error**       | `error_attributes.is_retryable`              | The error may be resolved by retrying the request.             |
| **Service Timeout Error**     | `error_attributes.service_timeout_error`     | The request timed out waiting for a response from the service. |
| **Authentication Error**      | `error_attributes.user_authentication_error` | The request could not be authenticated.                        |
| **Invalid Request Error**     | `error_attributes.user_invalid_request`      | The request was rejected because it was malformed or invalid.  |
| **User Rate Limit Exceeded**  | `error_attributes.user_ratelimit_exceeded`   | The request was rejected because a rate limit was exceeded.    |
| **Service Unavailable Error** | `error_attributes.service_unavailable_error` | The service was temporarily unavailable.                       |

### How Error Attributes Are Assigned

Error Attributes are not mutually exclusive - one or multiple Error Attributes may be set to `true` whenever a service fails.

When a service call fails for any reason, **Any Error Occurred** will be set to `true`. Alloy may also set other attributes to `true` depending on how much context is available surrounding the failure, and will classify the failure as specifically as the response allows:

1. **Vendor-specific mapping** — in some cases, a service returns a meaningful error code of its own, and Alloy's integration maps that code directly to the relevant attributes.
2. **HTTP status** — otherwise, if the service returned an HTTP error response, the status code determines the attributes.
3. **Unclassified failure** — if neither applies, only **Any Error Occurred** is set.

Where no vendor-specific mapping exists, HTTP status codes resolve as follows. **Any Error Occurred** is `true` in every case.

| HTTP status         | Error Attributes set to `true`              |
| ------------------- | ------------------------------------------- |
| `401`, `403`        | Authentication Error, Invalid Request Error |
| `429`               | User Rate Limit Exceeded, Retryable Error   |
| Other `4xx`         | Invalid Request Error                       |
| `502`, `503`, `504` | Service Unavailable Error, Retryable Error  |
| Other `5xx`         | Retryable Error                             |

Separately, when a service does not respond at all within Alloy's internal time limit for the call, Alloy sets **Service Timeout Error**, **Has Retryable Error**, and **Any Error Occurred**.

<Callout icon="🚧" theme="warn">
  ### An attribute set to `false` means Alloy did not positively identify that cause, not that the cause has been ruled out. Design tags around the attribute you expect to be `true`, and use **Any Error Occurred** as your catch-all.
</Callout>

### Using Error Attributes in Policy

Error Attributes behave like normal boolean attributes and compose with Alloy's standard workflow and decisioning tools.

## Workflow Failure Tags

Within Alloy's workflow builder, you can configure tags that are applied when [a specific service fails](https://help.alloy.com/hc/en-us/articles/8503430872987-Data-Services-Failure-Tags). Using the **Apply Tag** action on service failure conditions allows you to track and filter failure events in the Alloy dashboard over time.

Failure tags are policy-specific and can be used in tandem with Rule-Based Notifications.

## Service Failure Handling

Service Failure Handling is a configuration option available on individual Workflow tags and service nodes. It determines how Alloy evaluates affected tags when a vendor service fails or returns no data — allowing you to define how your policy behaves in failure scenarios rather than defaulting to Manual Review for every partial evaluation.

When a service failure occurs and a tag depends on data from that service, you can configure one of three behaviors:

| Option                        | Behavior                                                                                                                                                                                                                          |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Apply Tag**                 | Alloy treats the tag as if it evaluated to `true`, regardless of the missing data. Use this to build dedicated "failure" tags that explicitly flag vendor failures and route the policy to a specific outcome.                    |
| **Do Not Apply Tag**          | Alloy treats the tag as if it evaluated to `false`. Use this when a service failure should not affect the application's outcome and the tag is optional to your decisioning logic.                                                |
| **Exit Workflow** *(default)* | Alloy exits the workflow early and returns a `206 Partial` response. The application typically lands in the lowest-precedence outcome — usually Manual Review. This is the default when no Service Failure default is configured. |

Alloy recommends configuring service failure handling liberally to maintain control over application outcomes during vendor failures.

## Best Effort Parser

The Best Effort parser is a Workflow-level setting that changes how threshold logic is evaluated when some input data is null or undefined.

In the default evaluation mode, if a tag's threshold logic references unavailable data, the tag immediately falls back to failure handling — even if the available data would already be sufficient to evaluate the condition. **Best Effort Parser changes this:** it attempts to evaluate the threshold using only the data that is available, resolving conditions wherever possible.

### Example

Consider a *Phone Risk* tag with the following thresholds:

```
If Ekata: Primary Phone: Is Prepaid is true
  or Ekata: Primary Phone: Country Code is matching (regex) /^(DO|UG|NG|LK)$/i
Then set tag phone_risk
```

If Ekata returned `Is Prepaid` as `true` but `Phone Country Code` was missing from Ekata's raw response:

* **Traditional parser:** The tag defaults to service failure handling due to the undefined `Country Code` threshold.
* **Best Effort parser:** The tag is set to `true` because the first `OR` clause resolved to `true`, making the entire condition safely resolvable.

### Resolution Table

| Tag Thresholds          | Traditional Parser Result                                                                                                                            | Best Effort Parser Result                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `undefined` OR `true`   | Tag is `undefined`; falls back to service failure handling. If set to **Exit Workflow**, the Evaluation exits early and assigns the default outcome. | Tag is `true` (set); no fallback to failure handling.                                                                    |
| `undefined` OR `false`  | Tag is `undefined`; falls back to service failure handling. If set to **Exit Workflow**, the Evaluation exits early and assigns the default outcome. | Tag is `undefined`; falls back to service failure handling but does **not** exit early even if **Exit Workflow** is set. |
| `undefined` AND `true`  | Tag is `undefined`; falls back to service failure handling. If set to **Exit Workflow**, the Evaluation exits early and assigns the default outcome. | Tag is `undefined`; falls back to service failure handling but does **not** exit early even if **Exit Workflow** is set. |
| `undefined` AND `false` | Tag is `undefined`; falls back to service failure handling. If set to **Exit Workflow**, the Evaluation exits early and assigns the default outcome. | Tag is `false` (not set); no fallback to failure handling.                                                               |

Unlike the traditional parser, Best Effort always **keeps processing the Evaluation until completion** instead of exiting early. This reduces manual review outcomes from partial vendor data without requiring service failure handling on every tag.

> **Beta Feature:** Best Effort parser is currently in beta. To enable it, log into your Alloy dashboard and click 'Support' or reach out to your dedicated Alloy contact.

## Manual Review, Action & Retry Nodes

When service failures can't be resolved through tag- or workflow-level configuration alone, Alloy's Journey Orchestration supports a retry pattern using Manual Review or Action Nodes. This is suited for transient service failures unrelated to data validation issues or configuration errors.

### Setup

1. **Configure a dedicated outcome** — Set up an *Exception* or *Service Failure* outcome in your Workflow for the failure scenario you want to handle.

2. **Route to a Review or Action Node** — Route Journey Applications that hit this outcome to a node in your Journey:
   * **Action Node** — Automatically triggers retries on an exponential backoff timer. Recommended for initial retry attempts up to a defined limit. Use the **Update Journey Application Action Node** endpoint to trigger retries via `PUT` requests.
   * **Manual Review Node** — Allows agents to review the failure before triggering a retry. Can be combined with an Action Node for an automated → manual fallback approach.

3. **Connect to a Retry Node** — Connect the Review/Action node outcome to a Retry node, which loops the application back through the Workflow containing the failed service.

This pattern retries service requests while **maintaining a single consolidated Journey Application** across all attempts.

> **Important:** This approach is not suitable for errors caused by data validation issues or Workflow/Journey configuration problems. If data or policy changes are needed to resolve the error, use Journey Application reruns instead (see below).

## Rerunning Journey Applications

[Journey Application reruns](https://developer.alloy.com/public/docs/rerunning-journey-applications) are the most flexible retry option — they offer a **consistent retry solution for all failure types**, including those caused by invalid data on the original submission. Unlike Retry Nodes, reruns always go through the latest active version of the Journey, making them the right choice when a policy update is also required.

Alloy defaults to the same Entity data submitted on the original application, which may be helpful when using Journey Application reruns to retrieve updated results for the same applicant(s). Optionally, you can modify or append fields on resubmission — supported both via API and in the dashboard.

Reruns can be initiated via API using the [**Rerun Journey Application**](https://developer.alloy.com/public/reference/post_journeys-journey-token-applications-journey-application-token-rerun) endpoint or through the Alloy dashboard.

### Automated Reruns

To trigger reruns automatically, configure a **custom terminal Journey outcome** dedicated to service failures. The outcome will be populated in the Journey Application `complete_outcome` field once processing finishes. Use this field, along with the `completed_application` webhook event, as the signal to trigger a rerun.

### Dashboard Reruns

Reruns can also be initiated manually from the Alloy dashboard — useful when data modifications or policy updates are required before the application can process successfully.

### Tracking Reruns

When a rerun is initiated, Alloy sends a `started_rerun_evaluation` webhook event attached to the original Journey Application in the `_embedded.events[]` array. Use this event to track rerun history in your system.

### External ID Behavior

* `external_application_id` carries over automatically to the rerun.
* `external_group_id` does **not** carry over, but is available in the response under `_embedded.rerun`:

```json
{
	...
  "_embedded": {
    "rerun": {
      "initiated_by": "api",
      "previous_journey_application_token": "JA-8amRtBU3M98EWa4Hq8j7",
      "root_external_group_id": "8331a098-4238-4e26-bbdf-9a5a103ce509",
      "root_journey_application_token": "JA-8amRtBU3M98EWa4Hq8j7"
    }
  }
	...
}
```