getsops/sops · error
no valid resource ID found in %q
Error message
no valid resource ID found in %q
What it means
newKMSClient validates that MasterKey.ResourceID matches the canonical GCP KMS crypto key path `projects/.../locations/.../keyRings/.../cryptoKeys/...` via regex. Anything else — aliases, partial paths, URLs, extra segments — is rejected before creating the client.
Source
Thrown at gcpkms/keysource.go:294
out["created_at"] = key.CreationDate.UTC().Format(time.RFC3339)
out["enc"] = key.EncryptedKey
return out
}
// TypeToIdentifier returns the string identifier for the MasterKey type.
func (key *MasterKey) TypeToIdentifier() string {
return KeyTypeIdentifier
}
// newKMSClient returns a GCP KMS client configured with the tokenSource
// or credentialJSON, and/or grpcConn, falling back to environmental defaults.
// It returns an error if the ResourceID is invalid, or if the setup of the
// client fails.
func (key *MasterKey) newKMSClient(ctx context.Context) (*kms.KeyManagementClient, error) {
re := regexp.MustCompile(`^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$`)
matches := re.FindStringSubmatch(key.ResourceID)
if matches == nil {
return nil, fmt.Errorf("no valid resource ID found in %q", key.ResourceID)
}
var opts []option.ClientOption
switch {
case key.tokenSource != nil:
opts = append(opts, option.WithTokenSource(key.tokenSource))
case key.credentialJSON != nil:
opts = append(opts, option.WithCredentialsJSON(key.credentialJSON))
default:
credentials, err := getGoogleCredentials()
if err != nil {
return nil, fmt.Errorf("credentials: failed to obtain credentials from %q: %w", SopsGoogleCredentialsEnv, err)
}
if credentials != nil {
opts = append(opts, option.WithCredentialsJSON(credentials))
break
}
View on GitHub (pinned to 13442bb981)
Solutions
- Set ResourceID to the full canonical path, e.g. projects/my-proj/locations/us-east1/keyRings/sops/cryptoKeys/sops-key.
- Generate it with: gcloud kms keys describe KEY --location L --keyring R --format 'value(name)'.
- Trim whitespace and remove any 'https://...' prefix or query string.
- If using key alternatives versions, reference the cryptoKey, not the cryptoKeyVersion.
Example fix
// before // resource_ids: ['projects/my-proj/locations/global/keyRings/sops'] // after // resource_ids: ['projects/my-proj/locations/global/keyRings/sops/cryptoKeys/my-key']
Defensive patterns
Strategy: validation
Validate before calling
var gcpKeyRe = regexp.MustCompile(`^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$`)
func validGCPResourceID(id string) bool { return gcpKeyRe.MatchString(strings.TrimSpace(id)) } Type guard
null
Try / catch
null
Prevention
- Generate ResourceIDs with `gcloud kms keys describe --format 'value(name)'` instead of typing them.
- Lint .sops.yaml resource_ids against the canonical regex in CI.
- Never paste console URLs or keyring-only paths as resource IDs.
When it happens
Trigger: EncryptContext/DecryptContext (and their tests) called with a MasterKey whose ResourceID is not exactly projects/P/locations/L/keyRings/R/cryptoKeys/K, e.g. a bare key name or a global-key path.
Common situations: Writing .sops.yaml creation rules by hand and using the key ring path instead of the crypto key path; copying a console URL fragment; omitting the location (e.g. using 'global' incorrectly); trailing slashes or whitespace.
Related errors
- invalid key ID format: expected 'region:key-uuid', got %q
- region cannot be empty in key ID: %q
- key UUID cannot be empty in key ID: %q
- cannot create GCP KMS service: %w
- failed to encrypt sops data key with GCP KMS key: %w
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/a13bfbb36d197f7e.
Report an issue: GitHub.