hashicorp/nomad · error

service (%s) failed validation: %v

Error message

service (%s) failed validation: %v

What it means

After environment interpolation, each service name on the task is validated via service.ValidateName. Names must be valid per Nomad/Consul naming rules (alphanumeric plus dashes, no illegal characters, length limits). Failures are collected into a multi-error prefixed with this message.

Source

Thrown at client/allocrunner/taskrunner/validate_hook.go:65

	// Validate the user
	// COMPAT(1.0) uses inclusive language. blacklist is kept for backward compatilibity.
	unallowedUsers := conf.ReadStringListAlternativeToMapDefault(
		[]string{"user.denylist", "user.blacklist"},
		config.DefaultUserDenylist,
	)
	checkDrivers := conf.ReadStringListToMapDefault("user.checked_drivers", config.DefaultUserCheckedDrivers)
	if _, driverMatch := checkDrivers[task.Driver]; driverMatch {
		if _, unallowed := unallowedUsers[task.User]; unallowed {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("running as user %q is disallowed", task.User))
		}
	}

	// Validate the Service names once they're interpolated
	for _, service := range task.Services {
		name := taskEnv.ReplaceEnv(service.Name)
		if err := service.ValidateName(name); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("service (%s) failed validation: %v", name, err))
		}
	}

	if len(mErr.Errors) == 1 {
		return mErr.Errors[0]
	}
	return mErr.ErrorOrNil()
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Rename the service to use only valid characters (letters, digits, dashes)
  2. Check that any env vars used in the name are defined in the task's env block
  3. Fix interpolation so the name does not resolve empty
  4. Read the wrapped error after the prefix — it names the exact rule violated

Example fix

// before
service { name = "${NOMAD_JOB_NAME}_api" }
// after
service { name = "${NOMAD_JOB_NAME}-api" }
Defensive patterns

Strategy: validation

Validate before calling

// pre-check interpolated service names
for _, svc := range task.Services {
    name := taskEnv.ReplaceEnv(svc.Name)
    if err := structs.ValidateServiceName(name); err != nil {
        return fmt.Errorf("service %q invalid: %w", svc.Name, err)
    }
}

Try / catch

if err := service.ValidateName(name); err != nil {
    // err names the violated rule (chars, length, emptiness)
    return fmt.Errorf("rename service %q — only alphanumerics and dashes allowed: %w", name, err)
}

Prevention

When it happens

Trigger: A service's Name (after taskEnv.ReplaceEnv interpolation) contains invalid characters, is empty because an interpolated variable was undefined, or violates Consul service-name constraints.

Common situations: Using service names with underscores, dots, or slashes; service name built from an env var like ${NAMESPACE} that renders empty or with invalid characters; copy-pasting Kubernetes-style names into Nomad services.

Related errors


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