# NautheraAuditPartitionMissing

No audit log partition is attached for the current month.

## Meaning

`nauthera_audit_partitions_missing{month="current"}` has been above 0 for five minutes:
the audit log, partitioned by calendar month in UTC, has no partition for this month.
Partition maintenance has not run, or has failed, for longer than its headroom
(`audit.partition_ahead_months`, 6). With `audit.partition_maintenance: external`
(`appendOnlyAudit` in the chart) only `nauthera-server maintain` creates partitions; with
the default, `internal`, every replica's maintenance pass and every boot creates them,
so a failure there is usually a privilege or lock problem.

## Impact

Records for this month land in the default partition, `audit_events_default`. Once it
holds a row for the month, that month's partition cannot be created until the row is
moved by hand, and partition creation, and with it every `maintain` run, fails. With
maintenance external, a pod that starts now refuses to start, so a rollout, a node drain
or a crash turns into an outage of sign-in. Auditors are not losing records, but the log
is in a state that needs manual repair.

## Diagnosis

1. Which mode: `audit.partition_maintenance` in the configuration (`appendOnlyAudit.enabled`
   in the chart means external).
2. External: the maintenance CronJob and its last runs:
   `kubectl -n <ns> get cronjob <name>-maintain` and `kubectl -n <ns> get jobs`, then
   `kubectl -n <ns> logs job/<job>` for the failing run.
3. Internal: the server log, `kubectl -n &lt;ns&gt; logs &lt;pod&gt; | jq 'select(.msg|startswith(
   "could not create audit log partitions"))'`.
4. With the database owner, whether rows already sit in the default partition:
   `SELECT count(*), min(occurred_at), max(occurred_at) FROM audit_events_default;`

## Mitigation

- Do not roll out, restart or drain the server's pods until a partition is attached.
- External: run maintenance now:
  `kubectl -n <ns> create job --from=cronjob/<name>-maintain <name>-maintain-manual`
  and follow its log to `nauthera-server maintain finished`. If it fails, fix what its log
  names (the owner credential in `secrets.ownerDatabaseDsn`, a lock, a timeout).
- Internal: fix the cause the log names (usually the server's role not owning the audit
  table), then restart one pod; a boot creates the partitions.
- Rows already in the default partition for this month: creation fails until they are
  moved into the month's partition by a database administrator. Do not delete them: they
  are audit records.

## Escalation

Page the identity platform owner and the database owner now; this is one restart away
from an outage. If maintenance fails although the owner credential and database are
healthy, or the server reports a missing partition that exists, open an issue with the
maintenance log, the list of partitions (`SELECT inhrelid::regclass FROM pg_inherits
WHERE inhparent = 'audit_events'::regclass;`) and the server version.

---

[Alert runbooks](https://www.nauthera.io/docs/v1/runbooks/alerts) · Generated from [`internal/runbook/alerts.yaml`](https://github.com/nauthera/nauthera-server/blob/main/internal/runbook/alerts.yaml) and [`operator/internal/runbook/alerts.yaml`](https://github.com/nauthera/nauthera-server/blob/main/operator/internal/runbook/alerts.yaml) in nauthera-server.
