hashicorp/nomad · error

unknown check: %s/%s

Error message

unknown check: %s/%s

What it means

UpdateTTLOpts in the Consul test helper (catalog_testing.go) updates the status of a known TTL check in a fake Consul agent. It throws 'unknown check: <namespace>/<id>' when the check ID is not present in the fake's check map for that namespace, meaning the test is trying to pass a TTL for a check that was never registered (or was registered under a different namespace).

Source

Thrown at command/agent/consul/catalog_testing.go:400

	return nil
}

// UpdateTTLOpts implements AgentAPI
func (c *MockAgent) UpdateTTLOpts(id string, output string, status string, q *api.QueryOptions) error {
	c.mu.Lock()
	defer c.mu.Unlock()

	c.hits++
	namespace := getNamespace(q)

	checks, nsExists := c.checks[namespace]
	if !nsExists {
		return fmt.Errorf("unknown checks namespace: %q", namespace)
	}

	check, checkExists := checks[id]
	if !checkExists {
		return fmt.Errorf("unknown check: %s/%s", namespace, id)
	}

	// Flip initial status to passing
	// todo(shoenig) why not just set to the given status?
	check.Status = "passing"
	c.checkTTLs[namespace][id]++

	return nil
}

// a convenience method for looking up a registered service by name
func (c *MockAgent) lookupService(namespace, name string) []*api.AgentServiceRegistration {
	c.mu.Lock()
	defer c.mu.Unlock()

	var services []*api.AgentServiceRegistration
	for _, service := range c.services[namespace] {
		if service.Name == name {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the check was registered before calling UpdateTTLOpts and that the ID matches exactly (case-sensitive).
  2. Pass the correct namespace that the check was registered under (with Consul namespaces enabled, check IDs are scoped per namespace).
  3. Register the check (or seed it in the fake agent's check map) before updating its TTL.

Example fix

// before
agent.UpdateTTLOpts("default", "web-check", api.HealthPassing)
// after
agent.RegisterCheck("default", "web-check", ...) // ensure it exists
agent.UpdateTTLOpts("default", "web-check", api.HealthPassing)
Defensive patterns

Strategy: validation

Validate before calling

if checks, ok := agent.Checks()[namespace]; !ok {
  return fmt.Errorf("namespace %q has no checks", namespace)
} else if _, ok := checks[id]; !ok {
  return fmt.Errorf("check %q not registered in %q", id, namespace)
}

Type guard

func checkExists(agent *TestAgent, namespace, id string) bool {
  checks := agent.Consul().Agent().Checks()
  _, ok := checks[id]
  return ok
}

Prevention

When it happens

Trigger: Calling UpdateTTLOpts(namespace, checkID, ...) on the testing Consul agent where the check was never added via registration, or the check exists in a different namespace, or the ID spelling/case differs.

Common situations: Unit tests simulating task/service health updates: the test registers a service but forgets the check, uses the wrong namespace after namespace support was added, or asserts TTL state for a deregistered check.

Related errors


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