hashicorp/nomad · error

provider %q for secret %q response contained error: %q

Error message

provider %q for secret %q response contained error: %q

What it means

The external secret plugin executed successfully but explicitly reported a logical failure in its FetchResponse.Error field. Nomad surfaces that message verbatim as a provider error for the specific secret. Unlike error 705, the plugin process ran fine — it is telling Nomad the secret could not be retrieved/produced for an application-level reason.

Source

Thrown at client/allocrunner/taskrunner/secrets/plugin_provider.go:58

		secretName: secretName,
		path:       path,
		env:        env,
	}
}

func (p *ExternalPluginProvider) InterpolateEnv(interpolate func(string) string) {
	for key, value := range p.env {
		p.env[key] = interpolate(value)
	}
}

func (p *ExternalPluginProvider) Fetch(ctx context.Context) (map[string]string, error) {
	resp, err := p.plugin.Fetch(ctx, p.path, p.env)
	if err != nil {
		return nil, fmt.Errorf("failed executing plugin %q for secret %q: %w", p.pluginName, p.secretName, err)
	}
	if resp.Error != nil {
		return nil, fmt.Errorf("provider %q for secret %q response contained error: %q", p.pluginName, p.secretName, *resp.Error)
	}

	formatted := make(map[string]string, len(resp.Result))
	for k, v := range resp.Result {
		formatted[fmt.Sprintf("secret.%s.%s", p.secretName, k)] = v
	}

	return formatted, nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the quoted message from the plugin — it states the actual reason (not found, denied, etc.) and fix the secret path or permissions.
  2. Verify the secret exists at the given path in the upstream secret backend.
  3. Check/renew the credentials the plugin uses to reach the backend.
  4. Re-run the task after correcting the secrets block so the hook refetches.

Example fix

// before: task secrets block referencing a nonexistent path
secrets { env = "db_pass" path = "kv/prod/dbpass" }
// after: corrected path that exists in the backend
secrets { env = "db_pass" path = "kv/prod/db/password" }
Defensive patterns

Strategy: validation

Validate before calling

// validate the secret path exists before referencing it in the job
v, err := vaultClient.KVv2("kv").Get(ctx, "prod/db/password")
if err != nil {
    return fmt.Errorf("secret path referenced in nomad job does not exist: %w", err)
}

Type guard

// guard the plugin response before use
func responseOK(resp *FetchResponse) bool {
    return resp != nil && resp.Error == nil
}

Prevention

When it happens

Trigger: Calling ExternalPluginProvider.Fetch when the plugin returns a response whose Error pointer is non-nil, e.g. secret path not found, auth to the secret backend denied, or the requested secret key absent.

Common situations: Wrong secret path in the task's secrets block; revoked or expired plugin credentials to the upstream vault; secret deleted or rotated out from under a running allocation; typo in secret key/field name.

Related errors


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