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
- Read the quoted message from the plugin — it states the actual reason (not found, denied, etc.) and fix the secret path or permissions.
- Verify the secret exists at the given path in the upstream secret backend.
- Check/renew the credentials the plugin uses to reach the backend.
- 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
- Lint job files against the secret backend (path + keys) in CI before nomad job run.
- Rotate plugin credentials before expiry and alert on upcoming expirations.
- Use distinct paths/namespaces per environment to avoid cross-env path mistakes.
- Prefer dynamic job templating (consul-template/vault stanza) over hard-coded paths.
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
- failed executing plugin %q for secret %q: %w
- %w: %q (wraps ErrPluginNotExists)
- %w: %q (wraps ErrPluginNotExecutable)
- namespace cannot contain template delimiters or parenthesis
- plugin not found
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c07e44b7ddaa64ec.
Report an issue: GitHub.