hashicorp/nomad · error

deployment not found

Error message

deployment not found

What it means

After validating the ID, Deployment.Fail looks the deployment up in the state store via DeploymentByID. If the store returns nil — the ID is well-formed but no deployment with that UUID exists — this error is thrown. Unlike 'missing deployment ID', the caller supplied an identifier; it simply does not match any deployment in Nomad's state (or was deleted/GC'd).

Source

Thrown at nomad/deployment_endpoint.go:128

	// Validate the arguments
	if args.DeploymentID == "" {
		return fmt.Errorf("missing deployment ID")
	}

	// Lookup the deployment
	snap, err := d.srv.fsm.State().Snapshot()
	if err != nil {
		return err
	}

	ws := memdb.NewWatchSet()
	deploy, err := snap.DeploymentByID(ws, args.DeploymentID)
	if err != nil {
		return err
	}
	if deploy == nil {
		return fmt.Errorf("deployment not found")
	}

	// Check namespace submit-job permissions
	if aclObj, err := d.srv.ResolveACL(args); err != nil {
		return err
	} else if !aclObj.AllowNsOpAnyOf(deploy.Namespace,
		acl.NamespaceCapabilitySubmitJob,
		acl.NamespaceCapabilityFailDeployment,
	) {
		return structs.ErrPermissionDenied
	}

	if !deploy.Active() {
		return structs.ErrDeploymentTerminalNoFail
	}

	// Call into the deployment watcher
	return d.srv.deploymentWatcher.FailDeployment(args, reply)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the ID with nomad deployment status <id> or GET /v1/deployment/<id> first
  2. Re-fetch the current deployment ID from the job: nomad job status <job> or GET /v1/job/<job>/deployments
  3. Confirm you are targeting the correct Nomad cluster/region (deployment IDs are per-cluster)
  4. If the deployment is already terminal, it cannot be failed again — check its Status first

Example fix

// before
nomad deployment fail f47ac10b-58cc-...   // id from another cluster

// after
DID=$(nomad job status web | awk '/Deployment/{print $2; exit}')
nomad deployment status "$DID" && nomad deployment fail "$DID"
Defensive patterns

Strategy: validation

Validate before calling

dep, _, err := client.Deployments().Get(id)
if err != nil || dep == nil {
    return fmt.Errorf("deployment %s does not exist in this cluster", id)
}

Type guard

func deploymentExists(c *api.Client, id string) bool {
    d, _, err := c.Deployments().Get(id)
    return err == nil && d != nil
}

Try / catch

_, _, err := client.Deployments().Fail(id, nil)
if err != nil && strings.Contains(err.Error(), "deployment not found") {
    return fmt.Errorf("stale deployment ID %s; re-resolve from job", id)
}

Prevention

When it happens

Trigger: Calling nomad deployment fail <id> / POST /v1/deployment/fail with a UUID that was never created, belongs to another cluster, or whose record was removed; typos or truncated UUIDs.

Common situations: Cross-environment scripts reusing a deployment ID from staging in production; failing a deployment after the associated job was purged; stale deployment IDs cached in CI configuration after a Nomad server state restore.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/1c6be2edd14dfb5e. Report an issue: GitHub.