hashicorp/nomad · warning

Allocation bucket doesn't exist and transaction is not…

Error message

Allocation bucket doesn't exist and transaction is not writable

What it means

Thrown by getAllocationBucket when the per-allocation child bucket for allocID is missing under the allocations bucket and the transaction is read-only. In a writable tx the bucket would be auto-created with CreateBucket, but reads cannot mutate the tree, so the lookup fails fast. Note the singular 'Allocation' distinguishes it from the root 'Allocations' bucket error.

Solutions

  1. Check whether the alloc bucket was deleted (e.g. by GC) and treat the error as 'alloc state absent'
  2. Use a writable Update transaction if the caller should create the alloc bucket
  3. Reconcile allocID against the client's tracked allocations; stale IDs will never have buckets
  4. Inspect the bolt DB (boltdd/bbolt CLI) to confirm which alloc buckets exist

Example fix

// before
allocState, err := db.GetAllocState(tx, allocID)
if err != nil {
    return err
}
// after: tolerate missing read-only bucket as absent state
allocState, err := db.GetAllocState(tx, allocID)
if err != nil {
    if strings.Contains(err.Error(), "Allocation bucket doesn't exist") {
        return nil // alloc state not persisted; treat as absent
    }
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

exists, err := allocBucketExists(db, allocID)
if err != nil {
    return err
}
if !exists {
    return fmt.Errorf("no persisted state for alloc %s", allocID)
}

Type guard

func isMissingAllocBucketErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "Allocation bucket doesn't exist")
}

Try / catch

allocState, err := db.GetAllocState(tx, allocID)
if isMissingAllocBucketErr(err) {
    return nil // state absent (never persisted or GC'd)
}
if err != nil {
    return err
}

Prevention

When it happens

Trigger: Calling GetAllocation/GetAllocState/db writes routed through a View() for an allocID whose bucket was never created (e.g. never restored after restart, deleted by DeleteAllocationBucket, or wiped state dir).

Common situations: Client restored from a backup missing that alloc's bucket; alloc state read after bucket deletion during GC; querying stale allocIDs against a rebuilt state DB; concurrent GC removing the alloc bucket while a read transaction runs.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/669bf13bc171ccc7. Report an issue: GitHub.

Appendix: source

Thrown at client/state/db_bolt.go:799

	// Retrieve the root allocations bucket
	allocations := tx.Bucket(allocationsBucketName)
	if allocations == nil {
		if !w {
			return nil, fmt.Errorf("Allocations bucket doesn't exist and transaction is not writable")
		}

		allocations, err = tx.CreateBucketIfNotExists(allocationsBucketName)
		if err != nil {
			return nil, err
		}
	}

	// Retrieve the specific allocations bucket
	key := []byte(allocID)
	alloc := allocations.Bucket(key)
	if alloc == nil {
		if !w {
			return nil, fmt.Errorf("Allocation bucket doesn't exist and transaction is not writable")
		}

		alloc, err = allocations.CreateBucket(key)
		if err != nil {
			return nil, err
		}
	}

	return alloc, nil
}

// getTaskBucket returns the bucket used to persist state about a
// particular task. If the root allocation bucket, the specific
// allocation or task bucket doesn't exist, they will be created as long as the
// transaction is writable.
func getTaskBucket(tx *boltdd.Tx, allocID, taskName string) (*boltdd.Bucket, error) {
	alloc, err := getAllocationBucket(tx, allocID)
	if err != nil {

View on GitHub (pinned to 482b49bf1a)