hashicorp/nomad · error

unknown deployment %q

Error message

unknown deployment %q

What it means

forceAdd looks up the deployment by ID in the state store before registering a watcher; if DeploymentByID returns nil the deployment does not exist, so the watcher returns this error rather than watching a nonexistent record.

Source

Thrown at nomad/deploymentwatcher/deployments_watcher.go:344

	}
}

// forceAdd is used to force a lookup of the given deployment object and create
// a watcher. If the deployment does not exist or is terminal an error is
// returned.
func (w *Watcher) forceAdd(dID string) (*deploymentWatcher, error) {
	snap, err := w.state.Snapshot()
	if err != nil {
		return nil, err
	}

	deployment, err := snap.DeploymentByID(nil, dID)
	if err != nil {
		return nil, err
	}

	if deployment == nil {
		return nil, fmt.Errorf("unknown deployment %q", dID)
	}

	return w.addLocked(deployment)
}

// getOrCreateWatcher returns the deployment watcher for the given deployment ID.
func (w *Watcher) getOrCreateWatcher(dID string) (*deploymentWatcher, error) {
	w.l.Lock()
	defer w.l.Unlock()

	// Not enabled so no-op
	if !w.enabled {
		return nil, notEnabled
	}

	watcher, ok := w.watchers[dID]
	if ok {
		return watcher, nil

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. List deployments with `nomad job deployments <job>` or `nomad deployment list` and use a valid active deployment ID
  2. If the deployment was GC'd, create a new deployment by resubmitting the job
  3. Double-check the deployment ID for typos/whitespace in scripts
  4. Persist deployment IDs only for their retention window; re-fetch before acting on old IDs

Example fix

// before
nomad deployment unblock 0a1b2c3d  // stale ID
// after
nomad deployment list | grep <job>  # copy the current active deployment ID
nomad deployment unblock <current-id>
Defensive patterns

Strategy: validation

Validate before calling

// resolve a live deployment ID before acting
deps, _ := client.Jobs().Deployments(jobID, nil)
if len(deps) == 0 { /* no deployment to act on */ }

Try / catch

try {
    watcher.forceAdd(depID)
} catch (e) {
    if (e.message.includes('unknown deployment')) {
        const deps = await listDeployments(jobID)
        if (deps.length) await watcher.forceAdd(deps[0].ID)
    } else { throw e }
}

Prevention

When it happens

Trigger: getOrCreateWatcher -> forceAdd with a deployment ID that is absent from the state store (never existed, typo'd, or already GC'd).

Common situations: Calling nomad deployment unblock/promote/fail with a mistyped or GC'd deployment ID; leader-failover rehydration referencing old IDs; automation using stale deployment IDs from an old run.

Related errors


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