{"record":{"id":"ec54aa8b9584ba84","repo":"hashicorp/nomad","slug":"nil-allocation","errorCode":null,"errorMessage":"nil allocation","messagePattern":"nil allocation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/client.go","lineNumber":3060,"sourceCode":"\tcfg := nsd.ServiceRegistrationHandlerCfg{\n\t\tDatacenter: c.Datacenter(),\n\t\tEnabled:    c.GetConfig().NomadServiceDiscovery,\n\t\tNodeID:     c.NodeID(),\n\t\tNodeSecret: c.secretNodeID(),\n\t\tRegion:     c.Region(),\n\t\tRPCFn:      c.RPC,\n\t\tCheckWatcher: serviceregistration.NewCheckWatcher(\n\t\t\tc.logger, nsd.NewStatusGetter(c.checkStore),\n\t\t),\n\t}\n\tc.nomadService = nsd.NewServiceRegistrationHandler(c.logger, &cfg)\n}\n\n// verifiedTasks asserts each task in taskNames actually exists in the given alloc,\n// otherwise an error is returned.\nfunc verifiedTasks(logger hclog.Logger, alloc *structs.Allocation, taskNames []string) ([]string, error) {\n\tif alloc == nil {\n\t\treturn nil, fmt.Errorf(\"nil allocation\")\n\t}\n\n\tif len(taskNames) == 0 {\n\t\treturn nil, fmt.Errorf(\"missing task names\")\n\t}\n\n\tgroup := alloc.Job.LookupTaskGroup(alloc.TaskGroup)\n\tif group == nil {\n\t\treturn nil, fmt.Errorf(\"group name in allocation is not present in job\")\n\t}\n\n\tverifiedTasks := make([]string, 0, len(taskNames))\n\n\t// confirm the requested task names actually exist in the allocation\n\tfor _, taskName := range taskNames {\n\t\tif !taskIsPresent(taskName, group.Tasks) {\n\t\t\tlogger.Error(\"task not found in the allocation\", \"task_name\", taskName)\n\t\t\treturn nil, fmt.Errorf(\"task %q not found in allocation\", taskName)","sourceCodeStart":3042,"sourceCodeEnd":3078,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/client.go#L3042-L3078","documentation":"Nomad's client helper `verifiedTasks` validates an allocation and requested task names before performing task-level API operations (e.g. logs/exec/signal). It throws \"nil allocation\" when the *structs.Allocation passed in is nil, because no validation or task lookup can proceed without one. This is a defensive check in the client layer to fail fast with a clear message instead of panicking on a nil dereference.","triggerScenarios":"Calling a client API that resolves tasks for an allocation while passing a nil allocation — typically when the caller obtained the allocation via a lookup that returned nil (unknown alloc ID) and did not check it before calling verifiedTasks.","commonSituations":"Using a stale or mistyped allocation ID that resolves to nil; querying a client node for an allocation it never ran; race conditions where the allocation was removed from the client's local state before the task-listing call.","solutions":["Fix the caller so a nil alloc is caught before reaching verifiedTasks — verify the allocation ID exists on this client","Re-fetch the allocation from the server if the client's local copy may have been GC'd","Check the alloc ID in your API request for typos or stale values from a previous deployment"],"exampleFix":"// before\nalloc := c.getAlloc(allocID)\nverified, err := verifiedTasks(logger, alloc, tasks) // panics/errors on nil\n// after\nalloc := c.getAlloc(allocID)\nif alloc == nil {\n    return fmt.Errorf(\"allocation %q not found on client\", allocID)\n}\nverified, err := verifiedTasks(logger, alloc, tasks)","handlingStrategy":"validation","validationCode":"if alloc == nil {\n    return fmt.Errorf(\"allocation %q not found: cannot verify tasks\", allocID)\n}\n// then call the client API","typeGuard":"func allocExists(alloc *structs.Allocation) bool {\n    return alloc != nil && alloc.ID != \"\"\n}","tryCatchPattern":"verified, err := verifiedTasks(logger, alloc, taskNames)\nif err != nil {\n    return fmt.Errorf(\"task verification failed: %w\", err)\n}","preventionTips":["Always check allocation-lookup results for nil before passing them on","Refresh allocation state from the server if the client may have GC'd it","Log the alloc ID when it resolves to nil to catch stale references early"],"tags":["nomad","client","allocation","nil-pointer"],"backgroundTag":"nil-allocation","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"}