hashicorp/nomad · error

%v: %q

Error message

%v: %q

What it means

The service name failed ValidateName (likely invalid characters or format after env-var placeholders were stripped); the error is wrapped so the real, un-stripped service name is reported as %q for debugging.

Source

Thrown at nomad/structs/services.go:771

			mErr = multierror.Append(mErr, err)
		}
	}

	return mErr.ErrorOrNil()
}

// Validate checks if the Service definition is valid
func (s *Service) Validate() error {
	var mErr multierror.Error

	// Ensure the service name is valid per the below RFCs but make an exception
	// for our interpolation syntax by first stripping any environment variables from the name

	serviceNameStripped := args.ReplaceEnvWithPlaceHolder(s.Name, "ENV-VAR")

	if err := s.ValidateName(serviceNameStripped); err != nil {
		// Log actual service name, not the stripped version.
		mErr.Errors = append(mErr.Errors, fmt.Errorf("%v: %q", err, s.Name))
	}

	switch s.AddressMode {
	case "", AddressModeAuto:
	case AddressModeHost, AddressModeDriver, AddressModeAlloc, AddressModeAllocIPv6:
		if s.Address != "" {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Service address_mode must be %q if address is set", AddressModeAuto))
		}
	default:
		mErr.Errors = append(mErr.Errors, fmt.Errorf("Service address_mode must be %q, %q, or %q; not %q", AddressModeAuto, AddressModeHost, AddressModeDriver, s.AddressMode))
	}

	switch s.OnUpdate {
	case "", OnUpdateIgnore, OnUpdateRequireHealthy, OnUpdateIgnoreWarn:
		// OK
	default:
		mErr.Errors = append(mErr.Errors, fmt.Errorf("Service on_update must be %q, %q, or %q; not %q", OnUpdateRequireHealthy, OnUpdateIgnoreWarn, OnUpdateIgnore, s.OnUpdate))
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Give the service a valid name (alphanumerics, dashes, underscores per Nomad name rules)
  2. Ensure any ${VAR} used in the name interpolates to a non-empty valid value at runtime
  3. Check the quoted name in the error for hidden/invalid characters

Example fix

// before
name = "${SERVICE}-${INVALID CHAR}"
// after
name = "${SERVICE}-web"
Defensive patterns

Strategy: try-catch

Validate before calling

if err := s.ValidateName(strings.ReplaceAll(s.Name, "${ENV-VAR}", "x")); err != nil {
    return err
}

Type guard

func isValidServiceName(name string) bool {
    return regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`).MatchString(name)
}

Try / catch

var mErr multierror.Error
if err := svc.Validate(); err != nil {
    var me *multierror.Error
    if errors.As(err, &me) {
        for _, e := range me.Errors {
            log.Printf("service %q invalid: %v", svc.Name, e)
        }
    }
}

Prevention

When it happens

Trigger: A service Name that is invalid (e.g. empty, or failing regex rules) after environment-variable interpolation placeholders are replaced, detected during Service.Validate and appended to the multi-error.

Common situations: Names with invalid characters; name composed solely of ${ENV_VAR} that resolves empty; names containing characters Nomad disallows.

Related errors


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