rqlite/rqlite · error

failed to create queue bucket: %w

Error message

failed to create queue bucket: %w

What it means

During NewQueue's initialization transaction, tx.CreateBucketIfNotExists(bucketName) must create the FIFO data bucket. Failure here (returned inside the db.Update transaction) is wrapped and ultimately surfaces as "failed to initialize buckets", causing queue startup to abort and the bbolt handle to be closed.

Source

Thrown at cdc/fifo.go:76

	// eventsChan is the write-side of the C channel.
	eventsChan chan *Event

	wg sync.WaitGroup
}

// NewQueue creates or opens a new persistent queue at the given file path.
func NewQueue(path string) (*Queue, error) {
	db, err := bbolt.Open(path, 0600, &bbolt.Options{Timeout: time.Second, NoFreelistSync: true})
	if err != nil {
		return nil, fmt.Errorf("failed to open boltdb: %w", err)
	}

	// Prepare the database buckets in a single transaction.
	var highestKey uint64
	if err := db.Update(func(tx *bbolt.Tx) error {
		if _, err := tx.CreateBucketIfNotExists(bucketName); err != nil {
			return fmt.Errorf("failed to create queue bucket: %w", err)
		}
		if _, err := tx.CreateBucketIfNotExists(metaBucketName); err != nil {
			return fmt.Errorf("failed to create meta bucket: %w", err)
		}
		// Ensure the meta bucket has a "max_key" entry.
		metaBucket := tx.Bucket(metaBucketName)
		if metaBucket.Get([]byte("max_key")) == nil {
			if err := metaBucket.Put([]byte("max_key"), uint64tob(0)); err != nil {
				return fmt.Errorf("failed to initialize max_key: %w", err)
			}
		}

		// Initialize state from the DB.
		var innerErr error
		highestKey, innerErr = getHighestKey(tx)
		if innerErr != nil {
			return fmt.Errorf("failed to get highest key: %w", innerErr)
		}

View on GitHub (pinned to 7586a4d1bd)

Solutions

  1. Check the wrapped error for the specific bbolt cause; bucket-creation failures usually indicate file corruption.
  2. Stop rqlited, back up the queue file, and delete it so a fresh queue is created — queued but undelivered CDC events will be lost.
  3. Verify disk health (SMART, dmesg) if corruption recurs.
  4. Re-run rqlited; CDC will resume capturing new changes into the fresh queue.

Example fix

// before: corrupt queue file blocks startup
$ mv ~/node/queue.db ~/node/queue.db.corrupt
// after: rqlited recreates queue cleanly on next start
$ rqlited -cdc-queue-path ~/node/queue.db ~/node
Defensive patterns

Strategy: fallback

Validate before calling

// no pre-call validation; corruption is detected at open — recover instead
// probe: bbolt open + read-only tx succeeds?
if db, err := bbolt.Open(path, 0600, &bbolt.Options{Timeout: time.Second}); err == nil {
    err = db.View(func(tx *bbolt.Tx) error { return nil })
    db.Close()
    // err != nil => file corrupt, replace before service start
}

Try / catch

q, err := cdc.NewQueue(path)
if err != nil {
    // fallback: archive corrupt queue and recreate (accepting event loss)
    os.Rename(path, path+".corrupt-")
    if q, err = cdc.NewQueue(path); err != nil {
        log.Fatalf("cdc queue unrecoverable: %v", err)
    }
    log.Printf("recreated corrupt CDC queue")
}

Prevention

When it happens

Trigger: The bbolt write transaction cannot create the main queue bucket — practically only when the database file is corrupted (invalid meta pages / freelist) or an internal bbolt error occurs during bucket creation.

Common situations: Corrupted bbolt file from disk corruption or an unsafe kill (though NoFreelistSync mitigates some of this); filesystem-level bit rot; running on unreliable storage.

Related errors


AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03). Data as JSON: /api/errors/d1af4e992659e62f. Report an issue: GitHub.