Skip to content

Elasticsearch restore does not restore the sts_k8s_logs data stream #126

Closed

Description

@viliakov

sts-backup elasticsearch restore never restores the sts_k8s_logs data stream, only its backing indices. This produces three failures.

1. Logs are orphaned after a successful restore. Since #40 (0.10.0), RestoreSnapshot is called with an explicit list of index names from restorableSnapshotIndices. The data stream name isn't in that list, so the .ds-sts_k8s_logs-* indices come back as ordinary hidden indices with no data stream. Seen restoring a 10-nonha backup into a fresh 150-ha instance (CLI 0.11.2, https://github.com/StackVista/stackstate/issues/882). The restore reported success, but there was no sts_k8s_logs data stream afterwards. Restoring {"indices":"sts_k8s_logs"} from the same snapshot repaired it.

2. A retry fails with 404. This is the original report, from verify-backup run 41391996239 (CLI 0.11.0). The first attempt stalled at 93/108 indices. Attempts 2 and 3 failed straight away:

Found 106 STS index(es) to delete
Rolling over datastream 'sts_k8s_logs'...
❌ Error: failed to rollover datastream: elasticsearch returned error: [404 Not Found] ... rollover target [sts_k8s_logs] does not exist

deleteAllSTSIndices rolls the data stream over whenever any .ds-sts_k8s_logs-* index is listed. Because of (1), those indices exist without the data stream.

3. Restore fails when the target is already ingesting logs. In that case the target has the data stream. deleteAllSTSIndices rolls it over, creating -000002, then deletes only the indices it listed beforehand, so the new write index survives. If the snapshot also contains a -000002, _restore fails with cannot restore index [.ds-sts_k8s_logs-<date>-000002] because an open index with same name already exists. Seen restoring a 150-ha backup into a 10-nonha instance (CLI 0.11.2, stackstate#882).

verify-backup doesn't catch (1) or (3). Its fresh instance receives no logs, and its Elasticsearch probe checks only topology events.

Manual workaround: DELETE _data_stream/sts_k8s_logs, restore {"indices":"sts_k8s_logs,sts_topology_events-*","include_global_state":false}, then sts-backup elasticsearch check-and-finalize --operation-id <snapshot>.

Done when

  • the restore deletes the target's sts_k8s_logs data stream, if present, instead of rolling it over, and still deletes orphaned backing indices
  • the restore request includes the data stream name, so sts_k8s_logs exists after restore with the snapshot's backing indices
  • regression tests cover: a target with no data stream, a target with orphaned backing indices, and a target whose live data stream has a write index that collides with the snapshot

Activity

  1. changed the title [-]Elasticsearch restore retry fails: rollover of sts_k8s_logs 404s after a partial restore[/-] [+]Elasticsearch restore does not restore the sts_k8s_logs data stream[/+] on Nov 9, 2026
  2. viliakov commented on Nov 9, 2026

    @viliakov
    ContributorAuthor
  3. self-assigned this
    on Nov 9, 2026
  4. viliakov commented on Nov 9, 2026

    @viliakov
    ContributorAuthor

    Design for the fix (verified against ES 8.19.16 source and experiments on sts-882-nonha). The full design, with tests and acceptance steps, is in mission-control plans/backup-cli-126-design.md.

    Cleanup (replaces the rollover)

    • If the STS listing contains any .ds-sts_k8s_logs-* index, DELETE _data_stream/sts_k8s_logs. A 404 means no data stream (orphans only), so carry on. A 200 means re-list the indices.
    • Delete every listed index that remains. This covers plain indices and orphans.
    • Guard: list again. If any STS index has reappeared, fail before _restore and print the check-and-finalize --finalize-only hint.

    Writers

    • Only the receiver writes sts_k8s_logs. The ES restore label already covers it in both profiles: receiver in non-HA, receiver-base and receiver-logs in HA.
    • But scale.ScaleDown waits for pods matching the workload label, and pods never carry that label. So the wait returns while the pods are still terminating. Fix: wait on each scaled workload's spec.selector. This applies to every datastore.

    Restore request

    • Append sts_k8s_logs to the explicit index list when the snapshot's data_streams contains it. Keep the backing index names; that request is valid.
    • If the snapshot has sts_k8s_logs backing indices but no sts_k8s_logs data stream, fail before scale-down, with nothing touched. Chart SLM snapshots (sts*) always include the stream, so only hand-made snapshots hit this.
    • partial is passed through unchanged.

    Unchanged

    • Completion tracking in restorableSnapshotIndices and check-and-finalize: the expected list stays concrete index names.
    • Config keys and chart.
    • Re-running after a stalled or interrupted restore is safe: deleting the data stream also works while its restore is still in flight.

    The uncommitted restore-logs-datastream work is kept as the base, plus the guard, the pod-wait fix and extra tests.

  5. added this to the v2.12.1 milestone on Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions