modulus outbox
Inspects and operates the transactional outbox database — the publisher-side messages that failed dispatch and stopped being retried. This is the counterpart to modulus dlq, which operates on broker dead-letter queues (the consumer side).
Usage
bash
# Show messages that exhausted their dispatch retries
modulus outbox list-failed
# Reset a message so the outbox processor retries it on the next poll
modulus outbox retry 8f3c2a1e-...
# Permanently delete a message
modulus outbox purge 8f3c2a1e-...
# Report how many delivered messages a 7-day retention purge would remove...
modulus outbox purge-processed --older-than-days 7
# ...then actually delete them
modulus outbox purge-processed --older-than-days 7 --confirmSubcommands
| Subcommand | Description |
|---|---|
list-failed [--max-attempts N] | List messages whose attempt count is at or above the threshold (default 5 — match your MessagingOptions.RetryPolicy.MaxAttempts). Shows id, attempts, creation time, event type, and last error. |
retry <messageId> | Reset the attempt counter and clear the last error. The OutboxProcessor picks the message up on its next poll. |
purge <messageId> | Permanently delete the message. |
purge-processed [--older-than-days N] [--batch-size N] [--confirm] | Bulk-delete successfully published messages whose ProcessedAt is older than N days (default 7), in batches (default 500) until drained. Without --confirm it only reports the matching row count. Unprocessed and dead-lettered rows are never touched. For automatic cleanup, enable MessagingOptions.Retention instead — see Outbox Pattern § Retention. |
Common Options
| Option | Description |
|---|---|
--connection-string <VALUE> | Database connection string. Default: ConnectionStrings:Default from --config. |
--config <PATH> | Path to appsettings.json (default: ./appsettings.json in the current directory). |
--provider <SqlServer|Sqlite> | EF Core provider for the outbox database (default: SqlServer). |
The outbox is an EF Core database — the same one every scaffolded module's DbContext uses — not the message broker. Connection resolution order:
--connection-string, if passed.ConnectionStrings:Defaultin the--configfile (default./appsettings.json).Messaging:ConnectionStringin the same file, as a legacy fallback only, with a warning. That key is the broker connection string (amqp://..., a Service Bus namespace, ...); it happens to work here only because older scaffolds had nothing else to fall back to. AddConnectionStrings:Default(or pass--connection-string) instead of relying on it.
If none of these resolve, or the resolved connection string can't actually reach a database, the command reports a friendly error and exits 1 — it never lets an unhandled exception escape.
Exit Codes
| Code | Meaning |
|---|---|
0 | Success (including an empty list-failed). |
1 | Connection could not be resolved, or the message id was not found. |
See Also
- Outbox Pattern — how messages get here
modulus dlq— the broker-side counterpart