hashicorp/nomad · error

cannot prepare consul tokens, no task specified

Error message

cannot prepare consul tokens, no task specified

What it means

This error is returned by consulHook.prepareConsulTokensForTask when the *structs.Task argument is nil. The code explicitly comments it as a programming error: Prerun always iterates over non-nil tasks from the task group, so a nil task means an internal caller bug, not a user configuration problem.

Source

Thrown at client/allocrunner/consul_hook.go:137

	if err := mErr.ErrorOrNil(); err != nil {
		revokeErr := h.revokeTokens(tokens)
		mErr = multierror.Append(mErr, revokeErr)
		return mErr.ErrorOrNil()
	}

	// write the tokens to hookResources
	if err := h.resourcesBackend.setConsulTokens(tokens); err != nil {
		h.logger.Error("unable to update tokens in state", "error", err)
	}

	return nil
}

func (h *consulHook) prepareConsulTokensForTask(task *structs.Task, tg *structs.TaskGroup, tokens map[string]map[string]*consulapi.ACLToken) error {
	if task == nil {
		// programming error
		return fmt.Errorf("cannot prepare consul tokens, no task specified")
	}

	clusterName := task.GetConsulClusterName(tg)
	consulConfig, ok := h.consulConfigs[clusterName]
	if !ok {
		return fmt.Errorf("no such consul cluster: %s", clusterName)
	}

	// Find task workload identity for Consul.
	widName := fmt.Sprintf("%s_%s", structs.ConsulTaskIdentityNamePrefix, consulConfig.Name)
	wid := task.GetIdentity(widName)
	if wid == nil {
		// Skip task if it doesn't have an identity for Consul since it doesn't
		// need a token.
		return nil
	}

	tokenName := widName + "/" + task.Name

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the caller (Prerun in consul_hook.go) to find why a nil task is passed; fix the missing nil check upstream
  2. Report it as a Nomad bug with the agent log and job spec if hit on a stock build
  3. Re-run the allocation; if it persists across restarts, capture a goroutine dump and file an issue

Example fix

// before
if err := h.prepareConsulTokensForTask(task, tg, tokens); err != nil { ... }
// after
if task != nil {
    if err := h.prepareConsulTokensForTask(task, tg, tokens); err != nil { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

if task == nil {
    return fmt.Errorf("skip: nil task passed to prepareConsulTokensForTask")
}
// otherwise proceed to call the hook
err := h.prepareConsulTokensForTask(task, tg, tokens)

Type guard

func taskNotNil(t *structs.Task) bool { return t != nil }

Prevention

When it happens

Trigger: Prerun (or another caller) invokes prepareConsulTokensForTask with a nil task pointer, e.g. iterating a task list containing nil entries or passing the result of a failed lookup without checking.

Common situations: Seen only during Nomad development, custom forks/patches to allocrunner, or a corrupted task-group lookup returning nil that isn't checked before calling the hook.

Related errors


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