hashicorp/nomad · error
unable to create KMS wrapper for provider %q: %w
Error message
unable to create KMS wrapper for provider %q: %w
What it means
A matching KMS provider config exists, but newKMSWrapper could not construct the go-kms-wrapping wrapper for it — bad credentials, missing required fields, or failed backend initialization. The underlying error is deliberately wrapped with the provider ID because raw library errors are opaque.
Source
Thrown at nomad/encrypter.go:487
for _, wrappedKey := range wrappedKeys.WrappedKeys {
providerID := wrappedKey.ProviderID
if providerID == "" {
providerID = string(structs.KEKProviderAEAD)
}
provider, ok := e.providerConfigs[providerID]
if !ok {
err := fmt.Errorf("no such KMS provider %q configured", providerID)
mErr = multierror.Append(mErr, err)
continue
}
wrapper, err := e.newKMSWrapper(provider, wrappedKeys.KeyID, wrappedKey.KeyEncryptionKey)
if err != nil {
// the errors that bubble up from this library can be a bit opaque, so
// make sure we wrap them with as much context as possible
err := fmt.Errorf("unable to create KMS wrapper for provider %q: %w", providerID, err)
mErr = multierror.Append(mErr, err)
continue
}
// fan-out decryption tasks for HA in Nomad Enterprise. we can use the
// key whenever any one provider returns a successful decryption.
go e.decryptWrappedKeyTask(completeCtx, wrapper, wrappedKeys.Meta(), wrappedKey, cipherSetCh)
decryptTasks++
}
if err := mErr.ErrorOrNil(); err != nil {
// If we have no tasks running, we can log an error for the operator and
// exit.
//
// It is likely any decryption configuration for the key is incorrect
// and follow-up attempts from other Raft/FMS calls for this key will
// also fail. We should not, however, continue with the server startupView on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped cause (%w) for the specific library error from the KMS SDK
- Validate the provider's required fields in the kms config block (kms_key_id, endpoint, region, etc.)
- Check cloud credentials on the server (instance profile, env vars, workload identity) and Vault token validity for transit
- Test the provider independently (aws kms describe-key, vault status) then restart the agent
Example fix
// before: kms block missing kms_key_id
kms = { provider = "awskms" region = "us-east-1" }
// after
kms = {
provider = "awskms"
kms_key_id = "alias/nomad-key"
region = "us-east-1"
} Defensive patterns
Strategy: validation
Validate before calling
// smoke-test the provider before the agent needs it
// awskms: aws kms describe-key --key-id alias/nomad-key --region us-east-1
// transit: vault token lookup && vault status
// gcpckms: gcloud kms keys describe nomad-key --keyring=... --location=...
if err := probeProvider("awskms"); err != nil {
return fmt.Errorf("KMS provider unreachable, wrapper creation would fail: %w", err)
} Try / catch
if err := srv.AddWrappedKey(wrappedKeys); err != nil {
if strings.Contains(err.Error(), "unable to create KMS wrapper") {
return fmt.Errorf("check KMS credentials and required config fields for this provider, then restart agent: %w", err)
}
return err
} Prevention
- Set every required field for the chosen provider (kms_key_id, region, endpoint) in the kms block
- Ensure cloud credentials are present in the agent's environment (instance profile, env vars, workload identity)
- Use renewable Vault tokens/AppRole for the transit provider
- Run a provider smoke test (describe-key / vault status) before agent startup in CI and ops runbooks
When it happens
Trigger: AddWrappedKey resolves the provider config and calls e.newKMSWrapper(provider, wrappedKeys.KeyID, wrappedKey.KeyEncryptionKey); wrapper construction fails on missing/invalid options (e.g. no kms_key_id, invalid Vault token, bad GCP/Azure credentials).
Common situations: Incomplete kms block in server config, expired Vault token for transit, IAM credentials not present on the server host, wrong region/endpoint, or env vars (AWS_*, GOOGLE_*, AZURE_*) absent in the agent's environment.
Related errors
- no such KMS provider %q configured
- dynamic workload users disabled
- nil config passed
- nil logger passed
- plugin config passed without binary name
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/023fd32fd2f09332.
Report an issue: GitHub.