benbjohnson/litestream · error

wait for db sync executor: %w

Error message

wait for db sync executor: %w

What it means

lockExec's semaphore Acquire failed while waiting for the running sync executor to finish. The context was cancelled or timed out before the exclusive sync slot became free — e.g. shutdown during an in-flight sync.

Source

Thrown at db.go:1255

func (db *DB) syncOnce(ctx context.Context, maxSyncWALBytes int64) (syncResult, error) {
	if err := db.lockExec(ctx); err != nil {
		return syncResult{}, err
	}
	defer db.execSem.Release(1)

	return db.syncLocked(ctx, maxSyncWALBytes)
}

func (db *DB) lockExec(ctx context.Context) error {
	if db.execSem.TryAcquire(1) {
		return nil
	}
	db.beginSyncExecutorWait()
	defer db.finishSyncExecutorWait()

	if err := db.execSem.Acquire(ctx, 1); err != nil {
		return fmt.Errorf("wait for db sync executor: %w", context.Cause(ctx))
	}
	return nil
}

func (db *DB) syncLocked(ctx context.Context, maxSyncWALBytes int64) (result syncResult, err error) {
	db.beginSyncDiag(diagOpSync)
	defer func() { db.finishSyncDiag(err) }()

	// Track total sync metrics.
	t := time.Now()
	defer func() {
		db.syncNCounter.Inc()
		if err != nil {
			db.syncErrorNCounter.Inc()
		}
		if isDiskFullError(err) {
			db.diskFullGauge.Set(1)
		} else {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Let the in-flight sync complete before shutting down
  2. Check whether the current sync is stuck (inspect sync diagnostics/metrics)
  3. Increase timeouts if syncs are routinely longer than the wait budget
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at db.go:1255 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/c9b0fbd126067558. Report an issue: GitHub.