hashicorp/nomad · error
Deployment ID %q couldn't be updated as it does not exist
Error message
Deployment ID %q couldn't be updated as it does not exist
What it means
Returned by UpdateDeploymentStatus when the deployment ID referenced in the status update request does not exist in the state store. This is a logical/consistency error: the client tried to mark a deployment via structs.DeploymentStatusUpdate whose DeploymentID has no matching record.
Source
Thrown at nomad/state/state_store.go:4809
}
if req.Eval != nil {
if err := s.nestedUpsertEval(txn, index, req.Eval); err != nil {
return err
}
}
return txn.Commit()
}
// updateDeploymentStatusImpl is used to make deployment status updates
func (s *StateStore) updateDeploymentStatusImpl(index uint64, u *structs.DeploymentStatusUpdate, txn *txn) error {
// Retrieve deployment
ws := memdb.NewWatchSet()
deployment, err := s.deploymentByIDImpl(ws, u.DeploymentID, txn)
if err != nil {
return err
} else if deployment == nil {
return fmt.Errorf("Deployment ID %q couldn't be updated as it does not exist", u.DeploymentID)
} else if !deployment.Active() {
return fmt.Errorf("Deployment %q has terminal status %q:", deployment.ID, deployment.Status)
}
// Apply the new status
copy := deployment.Copy()
copy.Status = u.Status
copy.StatusDescription = u.StatusDescription
copy.ModifyIndex = index
copy.ModifyTime = u.UpdatedAt
// check each TaskGroup for ProgressDeadline and reset RequireProgressBy
// to ProgressDeadline if the deployment is running or paused. This is to
// ensure that the RequireProgressBy is reset on a deployment that has been
// paused and resumed.
for _, dState := range copy.TaskGroups {
if dState == nil || dState.ProgressDeadline == 0 {
continueView on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the deployment ID exists (nomad deployment status <id>) before updating
- Re-fetch the deployment from the state store; drop the update if it was GC'd
- Ensure the job/deployment is not deregistered concurrently
- Re-run the deployment flow to create a fresh deployment
Defensive patterns
Strategy: validation
Validate before calling
dep, _, err := state.DeploymentByID(nil, u.DeploymentID)
if err != nil { return err }
if dep == nil {
return fmt.Errorf("deployment %s no longer exists; skipping update", u.DeploymentID)
} Type guard
func deploymentActive(s *state.StateStore, id string) bool {
d, _, err := s.DeploymentByID(nil, id)
return err == nil && d != nil && d.Active()
} Try / catch
err := srv.raft.Apply(updateReq).Error()
if err != nil && strings.Contains(err.Error(), "does not exist") {
// deployment was GC'd; drop the update instead of failing the eval
} Prevention
- Re-fetch the deployment before applying status updates
- Handle job deletion removing deployments
- Drop updates for GC'd deployment IDs
When it happens
Trigger: DeploymentStatusUpdate raft operation with a DeploymentID that was never created or has since been garbage collected (e.g. job deregistration removed the deployment).
Common situations: Scheduler/RPC racing with job deletion; clients caching a stale deployment ID; replaying an old evaluation against a rebuilt state store.
Related errors
- unknown deployment %q
- eval not found
- deployment promotion cannot be undone
- variable doesn't exist
- deployment not found
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/f731bbee41dd59b5.
Report an issue: GitHub.