{"record":{"id":"598ad96f00bf801c","repo":"hashicorp/nomad","slug":"exec-not-possible-client-status-of-allocation-s","errorCode":null,"errorMessage":"exec not possible, client status of allocation %s is %s","messagePattern":"exec not possible, client status of allocation (.+?) is (.+?)","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"nomad/client_alloc_endpoint.go","lineNumber":546,"sourceCode":"\t\treturn\n\t}\n\tif err != nil {\n\t\thandleStreamResultError(err, nil, encoder)\n\t\treturn\n\t}\n\n\t// Check node read permissions\n\tif aclObj, err := a.srv.ResolveACL(&args); err != nil {\n\t\thandleStreamResultError(err, nil, encoder)\n\t\treturn\n\t} else if !aclObj.AllowNsOp(alloc.Namespace, acl.NamespaceCapabilityAllocExec) {\n\t\t// client ultimately checks if AllocNodeExec is required\n\t\thandleStreamResultError(structs.ErrPermissionDenied, nil, encoder)\n\t\treturn\n\t}\n\n\tif alloc.ClientTerminalStatus() {\n\t\thandleStreamResultError(fmt.Errorf(\"exec not possible, client status of allocation %s is %s\", alloc.ID, alloc.ClientStatus),\n\t\t\tnew(int64(http.StatusBadRequest)), encoder)\n\t\treturn\n\t}\n\n\t// Handle job ID if requested.\n\tif args.JobID != \"\" {\n\t\t// Verify job exists.\n\t\tjob, err := snap.JobByID(nil, args.Namespace, args.JobID)\n\t\tif err != nil {\n\t\t\thandleStreamResultError(err,\n\t\t\t\tnew(int64(http.StatusInternalServerError)), encoder)\n\t\t\treturn\n\t\t}\n\t\tif job == nil {\n\t\t\thandleStreamResultError(\n\t\t\t\tfmt.Errorf(\"job %s not found in namespace %s\", args.JobID, args.Namespace),\n\t\t\t\tnew(int64(http.StatusNotFound)), encoder)\n\t\t\treturn","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/client_alloc_endpoint.go#L528-L564","documentation":"Nomad's AllocExec handler rejects an exec request when the target allocation's client status is terminal (completed, failed, or lost), meaning the task's process tree no longer exists on the node. The server checks alloc.ClientTerminalStatus() before opening the exec stream and returns HTTP 400 wrapped in this message. It is thrown because exec requires a live task to attach to.","triggerScenarios":"Calling `nomad alloc exec <allocID> ...` (or the AllocExec RPC) with an allocation whose ClientStatus is 'complete', 'failed', or 'lost'.","commonSituations":"Scripts/race conditions where the job finished between listing allocations and exec'ing into it; exec'ing into a batch/parameterized job's finished alloc; targeting an alloc from a failed deployment; node restart marking allocs lost.","solutions":["Verify the allocation is still running: `nomad alloc status <alloc-id>` and check ClientStatus is 'run' before exec'ing.","Re-run the job or use `nomad job run` to create a new live allocation, then exec into that.","For batch work, capture logs instead: `nomad alloc logs <alloc-id>` works on terminal allocs.","In automation, retry exec with backoff or handle terminal status by skipping/relaunching."],"exampleFix":"// before\nexec(allocID) // alloc may be terminal\n// after\nconst st = getAlloc(allocID)\nif (st.clientStatus !== 'run') { logs(allocID); return } // skip exec for terminal alloc\nexec(allocID)","handlingStrategy":"validation","validationCode":"const status = await nomad.allocStatus(allocID)\nif (['complete','failed','lost'].includes(status.clientStatus)) {\n  throw new SkipExecError(`alloc ${allocID} terminal (${status.clientStatus}); use logs instead`)\n}\nreturn exec(allocID)","typeGuard":"const isRunnable = (a) => a != null && a.clientStatus === 'run'","tryCatchPattern":null,"preventionTips":["Check alloc ClientStatus with `nomad alloc status` immediately before exec.","Treat batch/parameterized jobs as exec-unfriendly; prefer logs.","In automation, poll until ClientStatus is 'run' with a timeout before exec.","Alert on exec attempts against terminal allocs to catch race conditions."],"tags":["nomad","exec","allocation-lifecycle"],"backgroundTag":"allocation-terminal-state","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"}