Skip to content

[Fleet] Fix package policy count filters: use NOT latest_revision:false instead of latest_revision:true#263717

Merged
juliaElastic merged 7 commits intoelastic:mainfrom
juliaElastic:fix-package-policy-latest-revision-bugs
Apr 17, 2026
Merged

[Fleet] Fix package policy count filters: use NOT latest_revision:false instead of latest_revision:true#263717
juliaElastic merged 7 commits intoelastic:mainfrom
juliaElastic:fix-package-policy-latest-revision-bugs

Conversation

@juliaElastic
Copy link
Copy Markdown
Contributor

@juliaElastic juliaElastic commented Apr 16, 2026

Summary

Fixes the latest_revision filter used when listing and counting package policies. The previous filter (latest_revision:true) excluded 8.x policies that never had latest_revision persisted to Elasticsearch, causing them to appear with a count of 0 in the Installed Integrations list after upgrading from 8.x to 9.x.

The fix changes all filters from latest_revision:true to NOT latest_revision:false. This treats a missing field as equivalent to true (i.e. a current revision), which is the correct semantic — a policy without the field is a current revision, not a previous one.

Root cause

The latest_revision field was introduced in SO model version 19 (package rollback feature, PR #222779). For policies created in 8.x, the field is absent in ES because:

  • The v2 migration backfill only runs on one node in a multi-node cluster; other nodes skip document transforms
  • Patch upgrades (e.g. 9.2.7 → 9.2.8) skip the backfill entirely since no outdated documents exist
  • The list aggregation uses perPage: 0, bypassing the read-time in-memory backfill path entirely

Changes

  • package_policies_aggregation.ts (Bug 1 + Bug 2): Change filter to NOT :false; add size: SO_SEARCH_LIMIT to terms aggregation to prevent ES default truncation at 10 buckets
  • services/epm/packages/get.ts (Bug 3): Add NOT latest_revision:false to getPackageUsageStats so :prev rollback docs are excluded from stats counts
  • services/package_policy.ts: Apply same filter fix to list(), listIds(), getAllItemsIds(), getCompiledVersionsForAgentPolicy(), and findAllForAgentPolicy()

Closes #262491
Closes https://github.com/elastic/ingest-dev/issues/7478

🤖 Generated with Claude Code

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 16, 2026

Catch flakiness early (recommended)

Recommended before merge: run the flaky test runner against this PR to catch flakiness early.

Trigger a run with the Flaky Test Runner UI or post this comment on the PR:

/flaky ftrConfig:x-pack/platform/test/fleet_api_integration/config.epm.ts:30 ftrConfig:x-pack/platform/test/fleet_api_integration/config.agent.ts:30

This check is experimental. Share your feedback in the #appex-qa channel.

Posted via Macroscope — Flaky Test Runner nudge

@juliaElastic juliaElastic marked this pull request as ready for review April 16, 2026 11:13
@juliaElastic juliaElastic requested a review from a team as a code owner April 16, 2026 11:13
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@botelastic botelastic Bot added the Team:Fleet Team label for Observability Data Collection Fleet team label Apr 16, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/fleet (Team:Fleet)

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 16, 2026

Approvability

Verdict: Needs human review

This PR modifies query filter logic across multiple Fleet package policy services to change which policies are included in counts and lists. While the intent is a bug fix (including 8.x policies without the latest_revision field), it changes runtime query behavior across several code paths. The author does not own any of the modified files, which are all owned by @elastic/fleet.

You can customize Macroscope's approvability policy. Learn more.

kuery
? `${savedObjectType}.attributes.latest_revision:true AND (${kuery})`
: `${savedObjectType}.attributes.latest_revision:true`
? `NOT ${savedObjectType}.attributes.latest_revision:false AND (${kuery})`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this part is repeated a lot maybe it could be extracted to a common function or something like this

Comment thread x-pack/platform/test/fleet_api_integration/apis/epm/list.ts
…d add test cleanup

- Extract repeated NOT latest_revision:false filter expression into a
  buildCurrentRevisionFilter() helper used across all 6 call sites
- Add try/finally cleanup to integration test that strips latest_revision
  from a SO doc, restoring it after assertions so it does not affect
  subsequent tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@juliaElastic juliaElastic requested a review from criamico April 16, 2026 15:35
When list() is called with fields:['policy_ids'] (e.g. from
checkFleetServerVersionsForSecretsStorage), the SO client returns
partial attributes and attributes.name is undefined — crashing with
TypeError on the audit log call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@criamico criamico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes! LGTM

@elasticmachine
Copy link
Copy Markdown
Contributor

⏳ Build in-progress, with failures

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #64 / Agents fleet_agents_api_privileges POST /api/fleet/agents/agent1/request_diagnostics should return a 200 for user: fleet_all_only
  • [job] [logs] FTR Configs #64 / Agents fleet_agents_api_privileges POST /api/fleet/agents/agent1/request_diagnostics should return a 200 for user: fleet_all_only
  • [job] [logs] FTR Configs #210 / Detections Response - Detection rule type telemetry @ess @serverless Detection rule status telemetry "indicator_match/threat_match" rule type should have non zero values for "index_duration"

History

@juliaElastic juliaElastic enabled auto-merge (squash) April 17, 2026 11:20
@juliaElastic juliaElastic merged commit 222e630 into elastic:main Apr 17, 2026
22 checks passed
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.2, 9.3, 9.4

https://github.com/elastic/kibana/actions/runs/24563264380

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Apr 17, 2026
…se instead of latest_revision:true (elastic#263717)

## Summary

Fixes the `latest_revision` filter used when listing and counting
package policies. The previous filter (`latest_revision:true`) excluded
8.x policies that never had `latest_revision` persisted to
Elasticsearch, causing them to appear with a count of 0 in the Installed
Integrations list after upgrading from 8.x to 9.x.

The fix changes all filters from `latest_revision:true` to `NOT
latest_revision:false`. This treats a missing field as equivalent to
`true` (i.e. a current revision), which is the correct semantic — a
policy without the field is a current revision, not a previous one.

### Root cause

The `latest_revision` field was introduced in SO model version 19
(package rollback feature, PR elastic#222779). For policies created in 8.x, the
field is absent in ES because:
- The v2 migration backfill only runs on one node in a multi-node
cluster; other nodes skip document transforms
- Patch upgrades (e.g. 9.2.7 → 9.2.8) skip the backfill entirely since
no outdated documents exist
- The list aggregation uses `perPage: 0`, bypassing the read-time
in-memory backfill path entirely

### Changes

- **`package_policies_aggregation.ts`** (Bug 1 + Bug 2): Change filter
to `NOT :false`; add `size: SO_SEARCH_LIMIT` to terms aggregation to
prevent ES default truncation at 10 buckets
- **`services/epm/packages/get.ts`** (Bug 3): Add `NOT
latest_revision:false` to `getPackageUsageStats` so `:prev` rollback
docs are excluded from stats counts
- **`services/package_policy.ts`**: Apply same filter fix to `list()`,
`listIds()`, `getAllItemsIds()`, `getCompiledVersionsForAgentPolicy()`,
and `findAllForAgentPolicy()`

Closes elastic#262491
Closes elastic/ingest-dev#7478

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit 222e630)
@kibanamachine
Copy link
Copy Markdown
Contributor

💔 Some backports could not be created

Status Branch Result
9.2 Backport failed because of merge conflicts
9.3 Backport failed because of merge conflicts
9.4

Note: Successful backport PRs will be merged automatically after passing CI.

Manual backport

To create the backport manually run:

node scripts/backport --pr 263717

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Apr 17, 2026
…on:false instead of latest_revision:true (#263717) (#264033)

# Backport

This will backport the following commits from `main` to `9.4`:
- [[Fleet] Fix package policy count filters: use NOT
latest_revision:false instead of latest_revision:true
(#263717)](#263717)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Julia
Bardi","email":"90178898+juliaElastic@users.noreply.github.com"},"sourceCommit":{"committedDate":"2026-04-17T11:41:48Z","message":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of latest_revision:true (#263717)\n\n## Summary\n\nFixes the
`latest_revision` filter used when listing and counting\npackage
policies. The previous filter (`latest_revision:true`) excluded\n8.x
policies that never had `latest_revision` persisted to\nElasticsearch,
causing them to appear with a count of 0 in the Installed\nIntegrations
list after upgrading from 8.x to 9.x.\n\nThe fix changes all filters
from `latest_revision:true` to `NOT\nlatest_revision:false`. This treats
a missing field as equivalent to\n`true` (i.e. a current revision),
which is the correct semantic — a\npolicy without the field is a current
revision, not a previous one.\n\n### Root cause\n\nThe `latest_revision`
field was introduced in SO model version 19\n(package rollback feature,
PR #222779). For policies created in 8.x, the\nfield is absent in ES
because:\n- The v2 migration backfill only runs on one node in a
multi-node\ncluster; other nodes skip document transforms\n- Patch
upgrades (e.g. 9.2.7 → 9.2.8) skip the backfill entirely since\nno
outdated documents exist\n- The list aggregation uses `perPage: 0`,
bypassing the read-time\nin-memory backfill path entirely\n\n###
Changes\n\n- **`package_policies_aggregation.ts`** (Bug 1 + Bug 2):
Change filter\nto `NOT :false`; add `size: SO_SEARCH_LIMIT` to terms
aggregation to\nprevent ES default truncation at 10 buckets\n-
**`services/epm/packages/get.ts`** (Bug 3): Add
`NOT\nlatest_revision:false` to `getPackageUsageStats` so `:prev`
rollback\ndocs are excluded from stats counts\n-
**`services/package_policy.ts`**: Apply same filter fix to
`list()`,\n`listIds()`, `getAllItemsIds()`,
`getCompiledVersionsForAgentPolicy()`,\nand
`findAllForAgentPolicy()`\n\nCloses #262491\nCloses
https://github.com/elastic/ingest-dev/issues/7478\n\n🤖 Generated with
[Claude
Code](https://claude.com/claude-code)\n\n---------\n\nCo-authored-by:
Claude Sonnet 4.6
<noreply@anthropic.com>","sha":"222e63005e6b113dd2ffffd7e75893a7be70e4be","branchLabelMapping":{"^v9.5.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Fleet","backport:version","v9.4.0","v9.5.0","v9.3.4","v9.2.9"],"title":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of
latest_revision:true","number":263717,"url":"https://github.com/elastic/kibana/pull/263717","mergeCommit":{"message":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of latest_revision:true (#263717)\n\n## Summary\n\nFixes the
`latest_revision` filter used when listing and counting\npackage
policies. The previous filter (`latest_revision:true`) excluded\n8.x
policies that never had `latest_revision` persisted to\nElasticsearch,
causing them to appear with a count of 0 in the Installed\nIntegrations
list after upgrading from 8.x to 9.x.\n\nThe fix changes all filters
from `latest_revision:true` to `NOT\nlatest_revision:false`. This treats
a missing field as equivalent to\n`true` (i.e. a current revision),
which is the correct semantic — a\npolicy without the field is a current
revision, not a previous one.\n\n### Root cause\n\nThe `latest_revision`
field was introduced in SO model version 19\n(package rollback feature,
PR #222779). For policies created in 8.x, the\nfield is absent in ES
because:\n- The v2 migration backfill only runs on one node in a
multi-node\ncluster; other nodes skip document transforms\n- Patch
upgrades (e.g. 9.2.7 → 9.2.8) skip the backfill entirely since\nno
outdated documents exist\n- The list aggregation uses `perPage: 0`,
bypassing the read-time\nin-memory backfill path entirely\n\n###
Changes\n\n- **`package_policies_aggregation.ts`** (Bug 1 + Bug 2):
Change filter\nto `NOT :false`; add `size: SO_SEARCH_LIMIT` to terms
aggregation to\nprevent ES default truncation at 10 buckets\n-
**`services/epm/packages/get.ts`** (Bug 3): Add
`NOT\nlatest_revision:false` to `getPackageUsageStats` so `:prev`
rollback\ndocs are excluded from stats counts\n-
**`services/package_policy.ts`**: Apply same filter fix to
`list()`,\n`listIds()`, `getAllItemsIds()`,
`getCompiledVersionsForAgentPolicy()`,\nand
`findAllForAgentPolicy()`\n\nCloses #262491\nCloses
https://github.com/elastic/ingest-dev/issues/7478\n\n🤖 Generated with
[Claude
Code](https://claude.com/claude-code)\n\n---------\n\nCo-authored-by:
Claude Sonnet 4.6
<noreply@anthropic.com>","sha":"222e63005e6b113dd2ffffd7e75893a7be70e4be"}},"sourceBranch":"main","suggestedTargetBranches":["9.4","9.3","9.2"],"targetPullRequestStates":[{"branch":"9.4","label":"v9.4.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.5.0","branchLabelMappingKey":"^v9.5.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/263717","number":263717,"mergeCommit":{"message":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of latest_revision:true (#263717)\n\n## Summary\n\nFixes the
`latest_revision` filter used when listing and counting\npackage
policies. The previous filter (`latest_revision:true`) excluded\n8.x
policies that never had `latest_revision` persisted to\nElasticsearch,
causing them to appear with a count of 0 in the Installed\nIntegrations
list after upgrading from 8.x to 9.x.\n\nThe fix changes all filters
from `latest_revision:true` to `NOT\nlatest_revision:false`. This treats
a missing field as equivalent to\n`true` (i.e. a current revision),
which is the correct semantic — a\npolicy without the field is a current
revision, not a previous one.\n\n### Root cause\n\nThe `latest_revision`
field was introduced in SO model version 19\n(package rollback feature,
PR #222779). For policies created in 8.x, the\nfield is absent in ES
because:\n- The v2 migration backfill only runs on one node in a
multi-node\ncluster; other nodes skip document transforms\n- Patch
upgrades (e.g. 9.2.7 → 9.2.8) skip the backfill entirely since\nno
outdated documents exist\n- The list aggregation uses `perPage: 0`,
bypassing the read-time\nin-memory backfill path entirely\n\n###
Changes\n\n- **`package_policies_aggregation.ts`** (Bug 1 + Bug 2):
Change filter\nto `NOT :false`; add `size: SO_SEARCH_LIMIT` to terms
aggregation to\nprevent ES default truncation at 10 buckets\n-
**`services/epm/packages/get.ts`** (Bug 3): Add
`NOT\nlatest_revision:false` to `getPackageUsageStats` so `:prev`
rollback\ndocs are excluded from stats counts\n-
**`services/package_policy.ts`**: Apply same filter fix to
`list()`,\n`listIds()`, `getAllItemsIds()`,
`getCompiledVersionsForAgentPolicy()`,\nand
`findAllForAgentPolicy()`\n\nCloses #262491\nCloses
https://github.com/elastic/ingest-dev/issues/7478\n\n🤖 Generated with
[Claude
Code](https://claude.com/claude-code)\n\n---------\n\nCo-authored-by:
Claude Sonnet 4.6
<noreply@anthropic.com>","sha":"222e63005e6b113dd2ffffd7e75893a7be70e4be"}},{"branch":"9.3","label":"v9.3.4","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.2","label":"v9.2.9","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
juliaElastic added a commit that referenced this pull request Apr 17, 2026
…on:false instead of latest_revision:true (#264041)

# Backport

This will backport the following commits from `main` to `9.3`:
- [Fleet] Fix package policy count filters: use NOT
latest_revision:false instead of latest_revision:true (#263717)

<!--- Backport version: 9.6.1 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Julia
Bardi","email":"90178898+juliaElastic@users.noreply.github.com"},"sourceCommit":{"committedDate":"2026-04-17T11:41:48Z","message":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of latest_revision:true
(#263717)","sha":"222e63005e6b113dd2ffffd7e75893a7be70e4be","branchLabelMapping":{"^v9.5.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Fleet","backport:version","v9.4.0","v9.5.0","v9.3.4"],"title":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of
latest_revision:true","number":263717,"url":"https://github.com/elastic/kibana/pull/263717","mergeCommit":{"message":"[Fleet]
Fix package policy count filters: use NOT latest_revision:false instead
of latest_revision:true
(#263717)","sha":"222e63005e6b113dd2ffffd7e75893a7be70e4be"}},"sourceBranch":"main","suggestedTargetBranches":["9.3"],"targetPullRequestStates":[{"branch":"9.4","label":"v9.4.0","url":"https://github.com/elastic/kibana/pull/264033","number":264033,"state":"OPEN"},{"branch":"9.3","label":"v9.3.4","state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels release_note:fix Team:Fleet Team label for Observability Data Collection Fleet team v9.3.4 v9.4.0 v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fleet]: Policy count incorrectly increases by one on Integration policies page after upgrading an integration

4 participants