{"record":{"id":"74f9ffdfa2ea4247","repo":"hashicorp/nomad","slug":"no-such-provider-q-configured","errorCode":null,"errorMessage":"no such provider %q configured","messagePattern":"no such provider %q configured","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"nomad/encrypter.go","lineNumber":951,"sourceCode":"\t\treturn nil, err\n\t}\n\n\tkekWrapper := &structs.KeyEncryptionKeyWrapper{}\n\tif err := json.Unmarshal(raw, kekWrapper); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmeta := kekWrapper.Meta\n\tif err = meta.Validate(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif kekWrapper.ProviderID == \"\" {\n\t\tkekWrapper.ProviderID = string(structs.KEKProviderAEAD)\n\t}\n\tprovider, ok := e.providerConfigs[kekWrapper.ProviderID]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"no such provider %q configured\", kekWrapper.ProviderID)\n\t}\n\n\t// the errors that bubble up from this library can be a bit opaque, so make\n\t// sure we wrap them with as much context as possible\n\twrapper, err := e.newKMSWrapper(provider, meta.KeyID, kekWrapper.KeyEncryptionKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to create key wrapper: %w\", err)\n\t}\n\twrappedDEK := kekWrapper.WrappedDataEncryptionKey\n\tif wrappedDEK == nil {\n\t\t// older KEK wrapper versions with AEAD-only have the key material in a\n\t\t// different field\n\t\twrappedDEK = &kms.BlobInfo{Ciphertext: kekWrapper.EncryptedDataEncryptionKey}\n\t}\n\tkey, err := wrapper.Decrypt(e.srv.shutdownCtx, wrappedDEK)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w (root key): %w\", ErrDecryptFailed, err)\n\t}","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/encrypter.go#L933-L969","documentation":"loadKeyFromStore restores a key from the keyring store: it reads the stored KEKWrapper and looks up its provider by ProviderID in e.providerConfigs. If that provider ID is not configured on this server, it returns \"no such provider %q configured\". The stored key cannot be decrypted because the KEK needed to unwrap it is not available.","triggerScenarios":"Restoring/decrypting a stored KEKWrapper whose ProviderID (defaulting to \"aead\" when empty) has no matching entry in the server's configured kms_config blocks.","commonSituations":"Server restarted without the kms_config block that originally wrapped the keyring; keys migrated between clusters with different KMS providers; provider renamed/removed in config; upgrading after changing providers without rotating keys.","solutions":["Add the missing kms_config block (same provider and ID) back to the server configuration and restart.","List the stored keyring metadata to see which provider ID the keys expect, and configure exactly that.","If the old provider is intentionally retired, rotate to a new KEK/provider first, then remove the old config.","For keys restored from a different cluster, ensure both clusters share the same KMS provider configuration."],"exampleFix":"// before: server config lacks the provider used by stored keys\n// after\nserver {\n  default_scheduler_config { }\n}\nkms_config {\n  provider = \"awskms\"\n  config { key_id = \"alias/nomad-default\" }\n}","handlingStrategy":"validation","validationCode":"// before restart/removal of a kms_config, verify no stored keys reference it:\n// list keyring key metadata and assert each ProviderID exists in providerConfigs\nfor _, meta := range storedKeyMetas {\n    if _, ok := providerConfigs[meta.ProviderID]; !ok {\n        return fmt.Errorf(\"config would orphan key %s (provider %s)\", meta.KeyID, meta.ProviderID)\n    }\n}","typeGuard":"func providerConfigured(id string, configs map[string]struct{}) bool {\n    if id == \"\" { id = \"aead\" }\n    _, ok := configs[id]\n    return ok\n}","tryCatchPattern":"key, err := loadKeyFromStore(...)\nif err != nil && strings.Contains(err.Error(), \"no such provider\") {\n    // restore the missing kms_config block or rotate keys before proceeding\n}","preventionTips":["Never remove a kms_config block until all keys it wraps are rotated to a new provider.","Keep a record (config-as-code) of which provider IDs originally wrapped the keyring.","Diff provider config before and after upgrades or cluster migrations."],"tags":["kms","keyring","configuration"],"backgroundTag":"kms-provider-not-configured","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}