hashicorp/nomad · error

secret provider cannot be empty

Error message

secret provider cannot be empty

What it means

Secret struct validation requires a non-empty Provider field identifying which secrets backend (e.g. vault) owns the secret. When s.Provider is "" the validator appends this error to the multierror, rejecting the secret record. (The acl/acl.go USED AT references are unrelated context.)

Source

Thrown at nomad/structs/structs.go:10639

}

func (s *Secret) Validate() error {
	if s == nil {
		return nil
	}

	var mErr multierror.Error

	if s.Name == "" {
		_ = multierror.Append(&mErr, errors.New("secret name cannot be empty"))
	}

	if !validSecretName.MatchString(s.Name) {
		_ = multierror.Append(&mErr, fmt.Errorf("secret name must match regex %s", validSecretName))
	}

	if s.Provider == "" {
		_ = multierror.Append(&mErr, errors.New("secret provider cannot be empty"))
	}

	if s.Path == "" {
		_ = multierror.Append(&mErr, errors.New("secret path cannot be empty"))
	}

	if s.Provider == "nomad" || s.Provider == "vault" {
		if len(s.Env) > 0 {
			_ = multierror.Append(&mErr, fmt.Errorf("%s provider cannot use the env block", s.Provider))
		}
	} else {
		if len(s.Config) > 0 {
			_ = multierror.Append(&mErr, fmt.Errorf("custom plugin provider %s cannot use the config block", s.Provider))
		}
	}

	return mErr.ErrorOrNil()
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set provider to a supported backend identifier (e.g. "vault") in the request payload or struct.
  2. Update the client/SDK version so the provider field is populated per the current API schema.
  3. Add client-side validation that fails fast when provider is missing before calling Nomad.
  4. Check field-name mapping/serialization tags if unmarshaling from another format (e.g. 'backend' vs 'provider').

Example fix

// before (Go)
s := &structs.Secret{Name: "app-creds", Path: "kv/app"}
// after
s := &structs.Secret{Name: "app-creds", Provider: "vault", Path: "kv/app"}
Defensive patterns

Strategy: validation

Validate before calling

func validateSecretProvider(s *structs.Secret) error {
	if s.Provider == "" {
		return fmt.Errorf("secret %q: provider is required (e.g. \"vault\")", s.Name)
	}
	return nil
}

Type guard

func hasProvider(s *structs.Secret) bool { return s != nil && s.Provider != "" }

Try / catch

if err := secret.Validate(); err != nil {
	if strings.Contains(err.Error(), "secret provider cannot be empty") {
		return fmt.Errorf("secret %q is missing its provider backend", secret.Name)
	}
	return err
}

Prevention

When it happens

Trigger: Submitting a secret creation request without the provider key, or constructing the Secret struct in Go with only Name/Path set and Provider left as the zero value before validation.

Common situations: Automation payloads copied from examples of a different API shape (provider nested elsewhere); version drift where the provider field was introduced later and older clients never send it; wrappers that only map name and path from user input.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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