ory/kratos · error
An error occurred while cleaning up expired data
Error message
An error occurred while cleaning up expired data
What it means
CleanupSQL wraps errors from d.Persister().CleanupDatabase with this message. CleanupDatabase deletes expired session/token rows in batches according to the configured sleep-tables and batch size; a failure here is a runtime database error during the deletion queries (lock timeouts, cancelled statements, permission issues).
Solutions
- Inspect the wrapped cause below this message to see which table/statement failed.
- Grant DELETE (and SELECT) on the Kratos tables to the configured DB user.
- Reduce database_cleanup_batch_size and/or increase sleep time to shorten transactions and avoid lock timeouts.
- Re-run the cleanup — it is resumable since it deletes in batches; check network stability for cron hosts.
Example fix
// before (huge single batches, lock timeouts) database_cleanup_batch_size: 100000 // after database_cleanup_batch_size: 500
Defensive patterns
Strategy: retry
Validate before calling
// Confirm the DB user may delete before the run:
var has bool
_ = db.QueryRow(`SELECT has_table_privilege(current_user, 'sessions', 'DELETE')`).Scan(&has)
if !has { return errors.New("DB user lacks DELETE privilege") } Try / catch
if out, err := exec.Command("kratos", "cleanup", "sql").CombinedOutput(); err != nil {
if strings.Contains(string(out), "while cleaning up expired data") {
log.Error("CleanupDatabase failed; inspect wrapped cause, lower batch size, re-run", "out", string(out))
}
} Prevention
- Grant DELETE/SELECT on all Kratos tables to the cleanup DB user.
- Keep database_cleanup_batch_size modest (hundreds, not hundreds of thousands) to avoid lock timeouts.
- Schedule cleanup off-peak and ensure cron hosts have stable DB connectivity.
- Re-run after transient failures — batched deletion is resumable.
When it happens
Trigger: The CleanupDatabase call returns an error mid-run: statement timeout/lock wait timeout on large tables, the DB user lacks DELETE permission, connection dropped during the batch loop, or invalid batch-size/sleep-table config.
Common situations: Running cleanup against a production DB with heavy contention; DB role without DELETE grants; very large expired-data backlog causing long-running statements that get killed; network interruptions in long cron jobs.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- expected to get the DSN as an argument, or the…
- An error occurred initializing cleanup
- an error occurred initializing migrations
- required config value "dsn" was not set
- expected zero or two args, got
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/5efb0ef12575d82b.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/cleanup/handler.go:63
return errors.New(`required config value "dsn" was not set`)
} else if err != nil {
return errors.Wrap(err, "An error occurred initializing cleanup")
}
err = d.Init(cmd.Context(), &contextx.Default{})
if err != nil {
return errors.Wrap(err, "An error occurred initializing cleanup")
}
keepLast := flagx.MustGetDuration(cmd, "keep-last")
err = d.Persister().CleanupDatabase(
cmd.Context(),
d.Config().DatabaseCleanupSleepTables(cmd.Context()),
keepLast,
d.Config().DatabaseCleanupBatchSize(cmd.Context()))
if err != nil {
return errors.Wrap(err, "An error occurred while cleaning up expired data")
}
return nil
}
View on GitHub (pinned to b86338da04)