JuliusBrussee/caveman · error
kms: unsupported provider
Error message
kms: unsupported provider %q
What it means
kms.New only supports the Scaleway provider; any provider value other than ProviderScaleway (case-insensitive, trimmed) is rejected at construction time so the client is always immutable and valid. The returned error names the offending value with %q so config typos are immediately visible.
Solutions
- Set cfg.Provider to exactly "scaleway" (case/whitespace are normalized).
- Check the environment variable or config file feeding cfg.Provider for stale values from another cloud.
- If you need another provider, this client does not support it — use that provider's SDK instead.
Example fix
// before
cfg := kms.Config{Provider: "aws-kms", Region: "fr-par", KeyID: id}
client, err := kms.New(cfg) // kms: unsupported provider "aws-kms"
// after
cfg := kms.Config{Provider: kms.ProviderScaleway, Region: "fr-par", KeyID: id}
client, err := kms.New(cfg) Defensive patterns
Strategy: validation
Validate before calling
if strings.ToLower(strings.TrimSpace(cfg.Provider)) != "scaleway" {
return fmt.Errorf("provider %q unsupported; only 'scaleway'", cfg.Provider)
}
client, err := kms.New(cfg) Try / catch
client, err := kms.New(cfg)
if err != nil {
if strings.Contains(err.Error(), "unsupported provider") {
return fmt.Errorf("KMS misconfiguration: %w", err)
}
return err
} Prevention
- Use the exported kms.ProviderScaleway constant instead of string literals.
- Validate provider config at startup, before first use.
- Name env vars explicitly (KMS_PROVIDER) and document allowed values.
- Add a unit test asserting New fails fast on bad providers.
When it happens
Trigger: Calling kms.New(cfg) with cfg.Provider set to "aws", "vault", "scw", "Scaleway " with odd casing is fine, but anything not exactly "scaleway" after ToLower/TrimSpace throws.
Common situations: Copy-pasting KMS config from an AWS/GCP project; an env var like KMS_PROVIDER defaulting to another cloud; typos such as "scaleway-kms" or empty provider string.
Related errors
- CAVEMAN_CCR_MAX_BYTES must be a positive integer
- ccr max storage bytes must be positive
- compat upstream name
- githubapp: app id is required
- kms: create request
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/eb36db1d98b2948f.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/kms/kms.go:78
token string
apiBaseURL string
httpClient *http.Client
decryptKeyIDs map[string]struct{}
}
// Envelope is safe to persist. Ciphertext is opaque provider output.
type Envelope struct {
Provider string `json:"provider"`
Region string `json:"region"`
KeyID string `json:"key_id"`
Ciphertext string `json:"ciphertext"`
}
// New validates configuration and returns immutable client.
func New(cfg Config) (*Client, error) {
provider := strings.ToLower(strings.TrimSpace(cfg.Provider))
if provider != ProviderScaleway {
return nil, fmt.Errorf("kms: unsupported provider %q", provider)
}
region, keyID := strings.TrimSpace(cfg.Region), strings.TrimSpace(cfg.KeyID)
if err := validateLocation(region, keyID); err != nil {
return nil, err
}
decryptKeyIDs := map[string]struct{}{keyID: {}}
for _, allowedKeyID := range cfg.AllowedDecryptKeyIDs {
allowedKeyID = strings.TrimSpace(allowedKeyID)
if err := validateLocation(region, allowedKeyID); err != nil {
return nil, err
}
decryptKeyIDs[allowedKeyID] = struct{}{}
}
token := strings.TrimSpace(cfg.AuthToken)
if len(token) < 20 {
return nil, errors.New("kms: auth token is required")
}
baseURL := strings.TrimRight(strings.TrimSpace(cfg.APIBaseURL), "/")View on GitHub (pinned to 3ee70a1026)