getsops/sops · error
could not parse %q into a valid Azure Key Vault MasterKey %v
Error message
could not parse %q into a valid Azure Key Vault MasterKey %v
What it means
NewMasterKeyFromURL parses an Azure Key Vault key URL of the form {vaultUrl}/keys/{keyName}/{keyVersion}. This error means the URL did not match that pattern, so a MasterKey cannot be constructed from it.
Source
Thrown at azkv/keysource.go:101
// NewMasterKey creates a new MasterKey from a URL, key name and (optional) version,
// setting the creation date to the current date.
func NewMasterKeyWithOptionalVersion(vaultURL string, keyName string, keyVersion string) (*MasterKey, error) {
key := newMasterKey(vaultURL, keyName, keyVersion)
if err := key.ensureKeyHasVersion(context.Background()); err != nil {
return nil, err
}
return key, nil
}
// NewMasterKeyFromURL takes an Azure Key Vault key URL, and returns a new
// MasterKey. The URL format is {vaultUrl}/keys/{keyName}/{keyVersion}.
func NewMasterKeyFromURL(url string) (*MasterKey, error) {
url = strings.TrimSpace(url)
re := regexp.MustCompile("^(https://[^/]+)/keys/([^/]+)(/[^/]*)?$")
parts := re.FindStringSubmatch(url)
if len(parts) < 3 {
return nil, fmt.Errorf("could not parse %q into a valid Azure Key Vault MasterKey %v", url, parts)
}
// Blank key versions are supported in Azure Key Vault, as they default to the latest
// version of the key. We need to put the actual version in the sops metadata block though
var key *MasterKey
if len(parts[3]) > 1 {
key = newMasterKey(parts[1], parts[2], parts[3][1:])
} else {
key = newMasterKey(parts[1], parts[2], "")
}
err := key.ensureKeyHasVersion(context.Background())
return key, err
}
// MasterKeysFromURLs takes a comma separated list of Azure Key Vault URLs,
// and returns a slice of new MasterKeys.
func MasterKeysFromURLs(urls string) ([]*MasterKey, error) {
var keys []*MasterKey
if urls == "" {View on GitHub (pinned to 13442bb981)
Solutions
- Use the full key identifier copied from the Azure portal: https://<vault-name>.vault.azure.net/keys/<key-name>/<key-version>
- Ensure the scheme is exactly https:// and there is no trailing slash issue or extra query string
- Verify the URL contains the literal /keys/ segment followed by a non-empty key name
- Trim whitespace/newlines if the URL came from a file or env var
Example fix
// before https://myvault.vault.azure.net/keys/ # missing key name // after https://myvault.vault.azure.net/keys/my-sops-key/1234abcd
Defensive patterns
Strategy: validation
Validate before calling
var azKeyURLRe = regexp.MustCompile(`^https://[^/]+/keys/[^/]+(/[^/]*)?$`)
func validateAzureKVURL(u string) error {
u = strings.TrimSpace(u)
if !azKeyURLRe.MatchString(u) {
return fmt.Errorf("invalid Azure KV key URL: %q (want https://vault/keys/name/version)", u)
}
return nil
} Type guard
func isWellFormedAzureKeyURL(u string) bool {
u = strings.TrimSpace(u)
re := regexp.MustCompile(`^https://[^/]+/keys/[^/]+(/[^/]*)?$`)
return re.MatchString(u)
} Try / catch
k, err := azkv.NewMasterKeyFromURL(u)
if err != nil {
return fmt.Errorf("bad azure_kv entry %q: %w", u, err)
} Prevention
- Copy key identifiers verbatim from the Azure portal 'Key Identifier' field
- Lint .sops.yaml URLs before running sops
- Trim whitespace from env/config inputs
When it happens
Trigger: Calling NewMasterKeyFromURL or MasterKeysFromURLs with a string missing https://, missing /keys/, missing key name, or containing unexpected whitespace/newlines that survive trimming.
Common situations: Copying a key ID from the Azure portal that uses vault:// or an incomplete path; forgetting the https:// scheme; using a managed-HSM URL with /keys under a different path shape; typos or extra query parameters; pasting a multi-line list into the sops config.
Related errors
- failed to get Azure token credential to retrieve key version
- failed to construct Azure Key Vault client to retrieve key v
- failed to fetch Azure Key to retrieve key version: %w
- failed to construct Azure Key Vault client to encrypt data:
- failed to encrypt sops data key with Azure Key Vault key '%s
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/b35f379043fb9730.
Report an issue: GitHub.