{"record":{"id":"974c45aca5e34a1d","repo":"hashicorp/nomad","slug":"modifying-node-pool-q-is-not-allowed","errorCode":null,"errorMessage":"modifying node pool %q is not allowed","messagePattern":"modifying node pool %q is not allowed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store_node_pools.go","lineNumber":136,"sourceCode":"\t}\n\n\treturn txn.Commit()\n}\n\nfunc (s *StateStore) upsertNodePoolTxn(txn *txn, index uint64, pool *structs.NodePool) error {\n\tif pool == nil {\n\t\treturn nil\n\t}\n\n\texisting, err := txn.First(TableNodePools, \"id\", pool.Name)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"node pool lookup failed: %w\", err)\n\t}\n\n\tif existing != nil {\n\t\t// Prevent changes to built-in node pools.\n\t\tif pool.IsBuiltIn() {\n\t\t\treturn fmt.Errorf(\"modifying node pool %q is not allowed\", pool.Name)\n\t\t}\n\n\t\texist := existing.(*structs.NodePool)\n\t\tpool.CreateIndex = exist.CreateIndex\n\t\tpool.ModifyIndex = index\n\t} else {\n\t\tpool.CreateIndex = index\n\t\tpool.ModifyIndex = index\n\t}\n\n\tif err := txn.Insert(TableNodePools, pool); err != nil {\n\t\treturn fmt.Errorf(\"node pool insert failed: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// fetchOrCreateNodePoolTxn returns an existing node pool with the given name","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store_node_pools.go#L118-L154","documentation":"upsertNodePoolTxn blocks any update to a built-in node pool (e.g. default, all). When an existing pool is found and the submitted pool IsBuiltIn(), the upsert returns this error instead of applying changes, protecting Nomad's internal pools from operator modification.","triggerScenarios":"Calling UpsertNodePools (or fetchOrCreateNodePoolTxn resolving a request to update) with a NodePool whose Name matches a built-in pool — e.g. trying to change the description, scheduler config, or node identity ttl of the \"default\" or \"all\" pool via the node pool update API/CLI.","commonSituations":"`nomad node pool update default ...` attempts; Terraform/automation applying node pool configs that include built-in pools; jobs or API clients sending a full pool object back that was fetched from /node/pools and happens to include built-ins.","solutions":["Only include custom (non-built-in) node pools in the upsert payload; skip pools where pool.IsBuiltIn() is true.","If tuning behavior of built-in pools is the goal, create a custom node pool and assign nodes/workloads to it instead.","Filter the response of node pool list APIs before replaying them as updates in automation.","On newer Nomad versions, check whether the desired setting is supported for built-in pools; otherwise keep them untouched."],"exampleFix":"// before\nfor _, pool := range pools {\n    stateStore.UpsertNodePools(idx, []*structs.NodePool{pool}) // includes \"default\"\n}\n\n// after\nfor _, pool := range pools {\n    if !pool.IsBuiltIn() {\n        stateStore.UpsertNodePools(idx, []*structs.NodePool{pool})\n    }\n}","handlingStrategy":"validation","validationCode":"for _, pool := range pools {\n    if pool.IsBuiltIn() {\n        continue // never upsert built-in pools\n    }\n    err := s.UpsertNodePools(idx, []*structs.NodePool{pool})\n    if err != nil {\n        return err\n    }\n}","typeGuard":"func isUpdatablePool(p *structs.NodePool) bool {\n    return p != nil && !p.IsBuiltIn()\n}","tryCatchPattern":"err := s.UpsertNodePools(idx, pools)\nif err != nil && strings.Contains(err.Error(), \"is not allowed\") {\n    // strip built-in pools from the batch and retry with custom pools only\n}","preventionTips":["Filter out built-in pools (default, all) from any node pool update automation.","Never replay node pool list API responses directly back as updates.","Create dedicated custom pools when custom scheduler or identity configuration is needed.","Add CI checks that reject configs referencing built-in pool names in write operations."],"tags":["nomad","state-store","node-pool","immutable-resource"],"backgroundTag":"builtin-resource-modification","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"}