{"record":{"id":"53604021916def1d","repo":"hashicorp/nomad","slug":"allocations-bucket-doesn-t-exist-and-transaction-i","errorCode":null,"errorMessage":"Allocations bucket doesn't exist and transaction is not writable","messagePattern":"Allocations bucket doesn't exist and transaction is not writable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/state/db_bolt.go","lineNumber":785,"sourceCode":"// Close releases all database resources and unlocks the database file on disk.\n// All transactions must be closed before closing the database.\nfunc (s *BoltStateDB) Close() error {\n\treturn s.db.Close()\n}\n\n// getAllocationBucket returns the bucket used to persist state about a\n// particular allocation. If the root allocation bucket or the specific\n// allocation bucket doesn't exist, it will be created as long as the\n// transaction is writable.\nfunc getAllocationBucket(tx *boltdd.Tx, allocID string) (*boltdd.Bucket, error) {\n\tvar err error\n\tw := tx.Writable()\n\n\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 {","sourceCodeStart":767,"sourceCodeEnd":803,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/state/db_bolt.go#L767-L803","documentation":"Thrown by getAllocationBucket when the top-level 'allocations' bucket is absent and the bolt transaction is read-only (not writable). Since buckets can only be created in writable transactions, getAllocationBucket refuses to proceed rather than silently returning a nil bucket. This prevents callers from mistaking a missing DB for an empty one.","triggerScenarios":"Calling GetAllocation (or any read path) via db.View() on a state DB that has no allocations bucket yet — e.g. a fresh/empty or wiped bolt file — or after a failed migration left the root bucket uncreated.","commonSituations":"Reading allocation state from a newly created or truncated client state DB; point-in-time copies of the state dir before any allocation ran; opening a state DB from a very old Nomad version pending upgrade migrations.","solutions":["Use db.Update (writable transaction) if you intend to create/initialize the allocations bucket","Run the client so upgrade migrations execute, which create the root bucket on a writable tx","If the DB is empty by design, tolerate this error and treat as 'no allocation state' in the caller","Verify you are opening the correct Nomad client state bolt file"],"exampleFix":"// before\nvar alloc *structs.Allocation\nerr := db.View(func(tx *boltdd.Tx) error {\n    a, err := db.GetAllocation(tx, allocID)\n    if err != nil {\n        return err\n    }\n    alloc = a\n    return nil\n})\n// after: fall back to writable tx on read-only bucket error\nvar alloc *structs.Allocation\nerr := db.View(func(tx *boltdd.Tx) error {\n    a, err := db.GetAllocation(tx, allocID)\n    if err != nil {\n        return err\n    }\n    alloc = a\n    return nil\n})\nif err != nil && strings.Contains(err.Error(), \"transaction is not writable\") {\n    err = db.Update(func(tx *boltdd.Tx) error {\n        a, err := db.GetAllocation(tx, allocID)\n        if err != nil {\n            return err\n        }\n        alloc = a\n        return nil\n    })\n}","handlingStrategy":"fallback","validationCode":"// pre-flight: ensure the state DB has been initialized at least once\nok, err := boltHasBucket(stateDBPath, \"allocations\")\nif err != nil || !ok {\n    // open in Update mode once to initialize buckets\n}","typeGuard":null,"tryCatchPattern":"err := db.View(func(tx *boltdd.Tx) error {\n    alloc, err = db.GetAllocation(tx, allocID)\n    return err\n})\nif err != nil && strings.Contains(err.Error(), \"Allocations bucket doesn't exist\") {\n    // treat as empty state: initialize via Update or return nil\n    alloc = nil\n    err = nil\n}","preventionTips":["Initialize the state DB once with a writable transaction at startup","Don't read from freshly created/empty state DBs with View","Keep the client's upgrade path intact so root buckets are created","Confirm the opened bolt file is the real Nomad state file"],"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"}