hashicorp/nomad · error

Duplicate secret %q found

Error message

Duplicate secret %q found

What it means

Task.Validate tracks task secret names in a map; if two secret blocks share the same name, the second occurrence logs 'Duplicate secret %q found'. Names must be unique because they become distinct env/file keys for the task's secrets.

Source

Thrown at nomad/structs/structs.go:8447

	}

	// Validate Identities
	for _, wid := range t.Identities {
		// Task.Canonicalize should move the default identity out of the Identities
		// slice, so if one is found that means it is a duplicate.
		if wid.Name == WorkloadIdentityDefaultName {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Duplicate default identities found"))
		}

		if err := wid.Validate(); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Identity %q is invalid: %w", wid.Name, err))
		}
	}

	secrets := make(map[string]bool)
	for _, s := range t.Secrets {
		if _, ok := secrets[s.Name]; ok {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Duplicate secret %q found", s.Name))
		} else {
			secrets[s.Name] = true
		}

		if s.Provider == SecretProviderVault && t.Vault == nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Secret %q has provider \"vault\" but no vault block", s.Name))
		}

		if err := s.Validate(); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Secret %q is invalid: %w", s.Name, err))
		}
	}

	return mErr.ErrorOrNil()
}

// validateServices takes a task and validates the services within it are valid
// and reference ports that exist.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Rename one of the duplicate secret blocks to a unique name
  2. Delete the redundant block if both point at the same source
  3. Fix the generator/template that emits secret names so each is unique

Example fix

// before
secrets {
  name   = "db_password"
  provider = "vault"
  path   = "kv/db"
}
secrets {
  name   = "db_password"
  provider = "vault"
  path   = "kv/db2"
}
// after
secrets {
  name   = "db_password"
  provider = "vault"
  path   = "kv/db"
}
secrets {
  name   = "db_password_v2"
  provider = "vault"
  path   = "kv/db2"
}
Defensive patterns

Strategy: validation

Validate before calling

names := map[string]bool{}
for _, s := range t.Secrets {
    if names[s.Name] { return fmt.Errorf("duplicate secret %q", s.Name) }
    names[s.Name] = true
}

Prevention

When it happens

Trigger: A task with two secrets { } blocks using the same name = "db_password", or an API-submitted Task whose Secrets slice contains repeated names.

Common situations: Copy-pasted secret blocks where only provider/env was changed but name left identical; templated job generation that appends secrets without uniquifying names; merging job fragments that each define the same secret name.

Related errors


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