Skip to content

Loki forgets EVERYTHING when loki-0 restarts: every namespace's history starts at 01:09Z 2026-09-09 (emptyDir still live despite persistence.enabled; no ingester WAL) #3773

Closed

Description

@rbuergi

What happened

While reading the memex 503 of 2026-09-09 (#3772) through Loki from a memex-cloud script: at 01:08Z a query over {namespace="memex"} returned both old pods' Application is shutting down... lines at 01:05:01Z (pods 76c99bdc6-9stvn, -g7f89). At 01:11Z the same query, same window, returned no line at all from either pod, and sum by (pod) (count_over_time({namespace="memex"}[70m])) no longer listed them. Between the two reads, monitoring/loki-0 was itself drained (01:09:08Z, together with loki-alertmanager-0 and the pushgateway) as the node-pool operation reached its node.

So the lines that had been ingested were lost with the ingester's unflushed chunks. deploy/aks/scripts/values.observability.yaml gives Loki a PVC (persistence.enabled: true) — that preserves flushed chunks and the index — but nothing there enables the ingester WAL (loki.config.ingester.wal.enabled + a dir on the persistent volume), so everything in memory at the moment of the restart is gone. The same file already documents that Promtail's WAL cannot be passed through the deprecated loki-stack chart; the Loki-side WAL is a different knob and is what would have kept these.

The lines lost were exactly the ones the incident needed: the first shutdown of the pair. The cluster-wide read at 01:09Z still carried the story, which is the only reason the cause was attributable.

Fix

  • Enable the ingester WAL in values.observability.yaml (loki.config.ingester.wal: {enabled: true, dir: /data/loki/wal, flush_on_shutdown: true} or the chart's equivalent — VERIFY by rendering that the key reaches the config, the way the Promtail note in that file does), on the persistent volume.
  • loki-0 sits on the system pool (nodeSelector: agentpool: system) and still gets drained with its node; flush_on_shutdown is what turns a graceful drain into a flush instead of a loss.
  • Note in the file that a drain of loki-0 is a read-it-now window for anything in flight.

Activity

  1. changed the title [-]Loki drops unflushed chunks when loki-0 is drained: ingester WAL is not enabled[/-] [+]Loki forgets EVERYTHING when loki-0 restarts: every namespace's history starts at 01:09Z 2026-09-09 (emptyDir still live despite persistence.enabled; no ingester WAL)[/+] on Sep 9, 2026
  2. rbuergi commented on Sep 9, 2026

    @rbuergi
    ContributorAuthor

    Verified the live storage boundary: the running monitoring/loki-0 uses grafana/loki:2.6.1, mounts volume storage at /data, and that volume is emptyDir. This directly explains loss on pod replacement: both chunk storage and the WAL are on ephemeral storage.

    The checked-in values render differently: a 30Gi storage volumeClaimTemplate mounted at /data, with ingester.wal.dir=/data/loki/wal. Loki 2.6.1 enables WAL by default: https://github.com/grafana/loki/blob/v2.6.1/pkg/ingester/wal.go#L38-L42 . Therefore absence of an explicit enabled:true value does not establish that WAL was disabled. Adding that setting alone would not fix the live durability defect.

    The required repair is to bring the live StatefulSet onto persistent storage, accounting for immutable volumeClaimTemplates and preserving or explicitly accepting the existing log window during migration. install-observability.sh already documents that immutable-field transition, but its final verification only prints commands and does not enforce their results. No live resources were modified during this investigation. The issue remains open until the storage migration and durability verification are complete.

  3. rbuergi commented on Sep 9, 2026

    @rbuergi
    ContributorAuthor

    Fixed on main — verified by file, not by PR state (the merge queue does not fire Closes links).

    git cat-file -e origin/main:deploy/aks/scripts/check-observability-values.sh   → present
    git show origin/main:deploy/aks/scripts/install-observability.sh | grep -c CHART_VERSION → 3
    

    Landed as #3835. All three of this issue's asks, plus the one it implied:

    1. Ingester WAL enabled — enabled, dir: /data/loki/wal, flush_on_shutdown (these had landed in c41bb0f, ~12 h after this issue was filed).
    2. VERIFIED by rendering, as this issue explicitly demanded — and the verification is now a gate, not a note. check-observability-values.sh runs on every pull request (Chart Gate → Observability values), and its job passed on the PR itself.
    3. The drain note is in values.observability.yaml: the WAL narrows the loss, it does not remove the gap, and loki-0 is still a read-it-now window while Promtail buffers with no WAL of its own.

    Plus the thing that made any verification here perishable: the chart was unpinned. helm upgrade --install grafana/loki-stack had no --version, so every run installed whatever upstream published last — an upstream restructure of loki.config could have stopped templating the WAL with no signal at all. Pinned to 2.10.3, in the installer and in the checker, moving together.

    🚨 The finding worth carrying forward

    The obvious gate — render, assert the keys arrive — is vacuous for Loki. loki-stack merges loki.config through verbatim, so a typo'd ingestor: reaches the render intact and passes. The first version of the gate shipped exactly that and passed the typo; only loki -verify-config rejects it (field ingestor not found in type loki.ConfigWrapper). It was caught by running the negative control, not by reading the code.

    Doc: Verifying Chart Values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions