{"record":{"id":"eb36db1d98b2948f","repo":"JuliusBrussee/caveman","slug":"kms-unsupported-provider-q","errorCode":null,"errorMessage":"kms: unsupported provider %q","messagePattern":"kms: unsupported provider %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/kms/kms.go","lineNumber":78,"sourceCode":"\ttoken         string\n\tapiBaseURL    string\n\thttpClient    *http.Client\n\tdecryptKeyIDs map[string]struct{}\n}\n\n// Envelope is safe to persist. Ciphertext is opaque provider output.\ntype Envelope struct {\n\tProvider   string `json:\"provider\"`\n\tRegion     string `json:\"region\"`\n\tKeyID      string `json:\"key_id\"`\n\tCiphertext string `json:\"ciphertext\"`\n}\n\n// New validates configuration and returns immutable client.\nfunc New(cfg Config) (*Client, error) {\n\tprovider := strings.ToLower(strings.TrimSpace(cfg.Provider))\n\tif provider != ProviderScaleway {\n\t\treturn nil, fmt.Errorf(\"kms: unsupported provider %q\", provider)\n\t}\n\tregion, keyID := strings.TrimSpace(cfg.Region), strings.TrimSpace(cfg.KeyID)\n\tif err := validateLocation(region, keyID); err != nil {\n\t\treturn nil, err\n\t}\n\tdecryptKeyIDs := map[string]struct{}{keyID: {}}\n\tfor _, allowedKeyID := range cfg.AllowedDecryptKeyIDs {\n\t\tallowedKeyID = strings.TrimSpace(allowedKeyID)\n\t\tif err := validateLocation(region, allowedKeyID); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdecryptKeyIDs[allowedKeyID] = struct{}{}\n\t}\n\ttoken := strings.TrimSpace(cfg.AuthToken)\n\tif len(token) < 20 {\n\t\treturn nil, errors.New(\"kms: auth token is required\")\n\t}\n\tbaseURL := strings.TrimRight(strings.TrimSpace(cfg.APIBaseURL), \"/\")","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/shared/platform/kms/kms.go#L60-L96","documentation":"kms.New only accepts the Scaleway provider: it lowercases and trims cfg.Provider, then requires it to equal ProviderScaleway (\"scaleway\"). Any other value — including empty — is rejected before region/key validation. The client is deliberately single-provider so envelope metadata can never redirect decryption to another KMS host.","triggerScenarios":"Constructing Config{Provider: \"aws\"} or \"gcp\" or \"\"; passing \"Scaleway \" works (trimmed/lowercased) but \"scw\" or \"scaleway-kms\" fails; config loaded from env where the provider variable was never set.","commonSituations":"Template config copied from a multi-provider example; env var naming mismatch (KMS_PROVIDER unset in the deployment); migration from another KMS leaving the old provider string in config; YAML indentation putting provider under the wrong block so it stays empty.","solutions":["Set cfg.Provider to exactly \"scaleway\" (case/whitespace tolerated)","If the provider env var is empty in production, verify the variable name and that the secret/config map actually injects it","If you need another KMS, this package does not support it — wrap at a higher layer or extend ProviderScaleway handling consciously","Add config validation at startup so this fails before first Encrypt/Decrypt call"],"exampleFix":"// before\ncfg := kms.Config{Provider: \"scw\", Region: \"fr-par\", KeyID: keyID}\nclient, err := kms.New(cfg)\n\n// after\ncfg := kms.Config{Provider: kms.ProviderScaleway, Region: \"fr-par\", KeyID: keyID}\nclient, err := kms.New(cfg)","handlingStrategy":"validation","validationCode":"func validKMSConfig(cfg kms.Config) bool {\n\treturn strings.ToLower(strings.TrimSpace(cfg.Provider)) == kms.ProviderScaleway\n}","typeGuard":"func isSupportedProvider(p string) bool {\n\treturn strings.ToLower(strings.TrimSpace(p)) == \"scaleway\"\n}","tryCatchPattern":"if _, err := kms.New(cfg); err != nil { if strings.Contains(err.Error(), \"unsupported provider\") { return fmt.Errorf(\"KMS provider must be %q, got %q\", kms.ProviderScaleway, cfg.Provider) } }","preventionTips":["Default Provider to kms.ProviderScaleway in config loading when unset","Fail fast at startup with a config validation pass","Keep provider in a single config location, not duplicated per environment"],"tags":["go","kms","config","scaleway"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}