﻿---
title: Troubleshoot anomaly detection datafeed project scope
description: The project_routing field decides which linked projects a cross-project search datafeed searches. This page covers routing that matches nothing, routing...
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8277/troubleshoot/elasticsearch/machine-learning/cps-datafeed-project-scope
products:
  - Elastic Cloud Serverless
  - Elasticsearch
  - Machine Learning
applies_to:
  - Elastic Cloud Serverless: Preview
  - Elastic Stack: Unavailable
---

# Troubleshoot anomaly detection datafeed project scope
The `project_routing` field decides which linked projects a cross-project search datafeed searches. This page covers routing that matches nothing, routing that matches too many projects, references to projects that no longer exist under an alias, and display counts that do not match the projects you expect.
Common symptoms include no results or origin-only results, slower extraction after linking projects, and job messages that reference a project alias that no longer exists.

## Where to look

Use these sources to gather diagnostic information:
- **Anomaly detection job job messages in Kibana**: Open **Machine Learning → Anomaly Detection**, select the job, and review the **Job messages** tab for audit entries and warnings about linked projects, credentials, or scope changes. On the **Datafeed** tab, **View datafeed counts** opens the datafeed chart flyout for extraction timing.
  The same entries are stored in `.ml-notifications-*`.
- **`GET _ml/datafeeds/{datafeed_id}`**: Shows the effective `project_routing` value and, when an internal cloud API key exists, `authorization.cloud_api_key.id`.
- **`GET _ml/datafeeds/{datafeed_id}/_stats`**: While the datafeed runs, shows `remote_cluster_stats` with `total_clusters`, `available_clusters`, `skipped_clusters`, `availability_ratio`, `stabilized_cluster_aliases`, and `per_cluster_consecutive_skips`. The object is absent until the first search cycle establishes a baseline.
- **`.ml-annotations-read`**: Scope-change annotations for the job. The annotation `event` field carries `search_scope_changed` (not the separate `type` field).
- **`GET /_project/tags`**: Lists linked projects and their tags so you can compare them with a routing expression.
- **Elastic Cloud console**: Review linked projects in [Link and manage projects](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8277/deploy-manage/cross-project-search-config/cps-config-link-and-manage).

If extraction failures are ongoing, check **Job messages** first. `remote_cluster_stats` from [get datafeed stats](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-ml-get-datafeed-stats) only updates after a cycle completes.

### Check the effective scope in Kibana

Open **Machine Learning → Anomaly Detection** and review the **Project scope** column. Each cell shows a parsed count out of the total project count (origin plus linked projects). For example, `2/5` means the expression targets 2 projects out of 5 available.
The parsed count comes from the routing expression text, not from which aliases match at runtime. To view the routing expression, open the job, go to the **Datafeed** tab, and check **Project scope**, or call `GET _ml/datafeeds/{datafeed_id}`.
A single wildcard expression like `_alias:production-*` shows `1`, even if it matches several linked projects at runtime.
When the parsed count is lower than the number of projects named in the expression, your user might lack permission to view one or more linked projects. The column reflects what you can see, not every alias the expression could match.

## Routing matches no project


### What you see

During create, update, or extraction, job messages or the API can report one of these machine learning-enriched errors.
On create or update:
Create failures use the same *Cannot update datafeed* wording even though the request is a put.
```txt
Cannot update datafeed [my-datafeed]: project_routing [_alias:nonexistent-*] matched no linked project (no matching project after applying project routing [_alias:nonexistent-*]). Link the missing project in Elastic Cloud project settings, or update project_routing to a valid linked alias (for example _origin for local-only scope).
```

During extraction or preview:
```txt
Datafeed [my-datafeed] cannot search any project: project_routing [_alias:nonexistent-*] matched no linked projects at run time (no matching project after applying project routing [_alias:nonexistent-*]). Link the missing project(s) in Elastic Cloud project settings, or update project_routing to an expression that matches at least one linked project (for example _origin for local-only scope).
```

The bracketed datafeed id, routing expression, and parenthesized cause vary with your configuration. The parenthesized text comes from Elasticsearch itself, typically in one of these forms:
```txt
no matching project after applying project routing [_alias:nonexistent-*]
```

```txt
No such project: [missing-project] with project routing [_alias:production-*]
```

The suggested `_origin` example in the machine learning messages is not a valid routing value. Use `_alias:_origin` for origin-project-only scope instead. See [Project routing in CPS](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8277/explore-analyze/cross-project-search/cross-project-search-project-routing).

| Situation                                                                                                        | Typical behavior                                              |
|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
| datafeed with empty `project_routing` and unqualified index patterns, with no linked projects                    | Create or update can succeed. The first run-time search fails |
| datafeed with unqualified index patterns and a `_alias:` expression that matches no linked tags, including typos | Create or update can succeed. The first run-time search fails |
| datafeed with qualified `project:index` patterns and `project_routing` that matches no linked tags               | Fails immediately on create or update                         |
| Qualified `project:index` references a project that does not exist or is unauthorized                            | Fails immediately on create or update                         |

A `project_routing` value that matches nothing is deferred to run time only when every entry in `indices` is unqualified. Any qualified `project:index` pattern, including one whose project alias is missing, fails immediately on create or update.

### Fix

Update routing to a valid `_alias:` expression, or link the missing project in [Link and manage projects](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8277/deploy-manage/cross-project-search-config/cps-config-link-and-manage). Stop the datafeed and close the anomaly detection job before you update routing. For step-by-step guidance on setting scope in Kibana or through the API, see [Change the project scope of an anomaly detection job](/elastic/docs-content/pull/8277/explore-analyze/machine-learning/anomaly-detection/ml-ad-run-jobs#ml-ad-cps-update).

### Verify

- The **Project scope** column shows the intended parsed/total count.
- `GET _ml/datafeeds/{datafeed_id}` returns the expected `project_routing` value.
- `GET _ml/datafeeds/{datafeed_id}/_stats` shows successful extraction cycles.


## Scope is wider than intended


### What you see

- datafeed extraction cycles take noticeably longer after new projects were linked.
- `GET _ml/datafeeds/{datafeed_id}/_stats` shows `remote_cluster_stats` fanning out to many linked projects you do not need.


### Fix

Narrow `project_routing` to the projects you need. Stop the datafeed and close the anomaly detection job before you update. See [Change the project scope of an anomaly detection job](/elastic/docs-content/pull/8277/explore-analyze/machine-learning/anomaly-detection/ml-ad-run-jobs#ml-ad-cps-update) for how to set **Project scope** in Kibana or update routing through the API.

### Verify

- The **Project scope** column shows the intended parsed/total count.
- `GET _ml/datafeeds/{datafeed_id}/_stats` shows `remote_cluster_stats` listing only the intended projects.
- Extraction cycle duration returns to expected levels.


## Stale project reference


### What you see

- Job messages or extraction errors reference a project alias that no longer appears in `GET /_project/tags` or the Cloud console linked-project list.
- `project_routing` still contains an `_alias:` tag that matched a project before it was renamed or unlinked.
- A qualified index pattern such as `old-alias:logs-*` names a project alias that is no longer linked.


### Fix

When `indices` contains a qualified `project:index` pattern, update both `project_routing` and the qualified index reference after a rename or unlink. Stop the datafeed and close the anomaly detection job before you update. See [Change the project scope of an anomaly detection job](/elastic/docs-content/pull/8277/explore-analyze/machine-learning/anomaly-detection/ml-ad-run-jobs#ml-ad-cps-update).
Changing `indices` also changes the cross-project search surface, which can re-key the internal cloud API key. See [Cloud credential problems](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8277/troubleshoot/elasticsearch/machine-learning/cps-datafeed-credentials).
If the project should still be in scope, re-establish the link in [Link and manage projects](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8277/deploy-manage/cross-project-search-config/cps-config-link-and-manage).

### Verify

- `GET _ml/datafeeds/{datafeed_id}` returns updated `project_routing` and `indices` values.
- Job messages no longer reference the stale alias.
- `GET _ml/datafeeds/{datafeed_id}/_stats` shows successful extraction cycles.