{"record":{"id":"669bf13bc171ccc7","repo":"hashicorp/nomad","slug":"allocation-bucket-doesn-t-exist-and-transaction-is","errorCode":null,"errorMessage":"Allocation bucket doesn't exist and transaction is not writable","messagePattern":"Allocation bucket doesn't exist and transaction is not writable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/state/db_bolt.go","lineNumber":799,"sourceCode":"\t// Retrieve the root allocations bucket\n\tallocations := tx.Bucket(allocationsBucketName)\n\tif allocations == nil {\n\t\tif !w {\n\t\t\treturn nil, fmt.Errorf(\"Allocations bucket doesn't exist and transaction is not writable\")\n\t\t}\n\n\t\tallocations, err = tx.CreateBucketIfNotExists(allocationsBucketName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// Retrieve the specific allocations bucket\n\tkey := []byte(allocID)\n\talloc := allocations.Bucket(key)\n\tif alloc == nil {\n\t\tif !w {\n\t\t\treturn nil, fmt.Errorf(\"Allocation bucket doesn't exist and transaction is not writable\")\n\t\t}\n\n\t\talloc, err = allocations.CreateBucket(key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn alloc, nil\n}\n\n// getTaskBucket returns the bucket used to persist state about a\n// particular task. If the root allocation bucket, the specific\n// allocation or task bucket doesn't exist, they will be created as long as the\n// transaction is writable.\nfunc getTaskBucket(tx *boltdd.Tx, allocID, taskName string) (*boltdd.Bucket, error) {\n\talloc, err := getAllocationBucket(tx, allocID)\n\tif err != nil {","sourceCodeStart":781,"sourceCodeEnd":817,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/state/db_bolt.go#L781-L817","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check whether the alloc bucket was deleted (e.g. by GC) and treat the error as 'alloc state absent'","Use a writable Update transaction if the caller should create the alloc bucket","Reconcile allocID against the client's tracked allocations; stale IDs will never have buckets","Inspect the bolt DB (boltdd/bbolt CLI) to confirm which alloc buckets exist"],"exampleFix":"// before\nallocState, err := db.GetAllocState(tx, allocID)\nif err != nil {\n    return err\n}\n// after: tolerate missing read-only bucket as absent state\nallocState, err := db.GetAllocState(tx, allocID)\nif err != nil {\n    if strings.Contains(err.Error(), \"Allocation bucket doesn't exist\") {\n        return nil // alloc state not persisted; treat as absent\n    }\n    return err\n}","handlingStrategy":"type-guard","validationCode":"exists, err := allocBucketExists(db, allocID)\nif err != nil {\n    return err\n}\nif !exists {\n    return fmt.Errorf(\"no persisted state for alloc %s\", allocID)\n}","typeGuard":"func isMissingAllocBucketErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"Allocation bucket doesn't exist\")\n}","tryCatchPattern":"allocState, err := db.GetAllocState(tx, allocID)\nif isMissingAllocBucketErr(err) {\n    return nil // state absent (never persisted or GC'd)\n}\nif err != nil {\n    return err\n}","preventionTips":["Track alloc lifecycles so reads never race bucket GC/deletion","Verify allocID validity before querying state","Rebuild/re-restore missing alloc buckets only in Update transactions","Audit backup/restore flows to confirm alloc buckets are preserved"],"tags":["database","bolt","read-only-transaction","bucket-missing"],"backgroundTag":"bolt-transaction-not-writable","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}