getsops/sops · error

error loading config: more than one destinations were found

Error message

error loading config: more than one destinations were found in a single destination rule, you can only use one per rule

What it means

A single destination rule may specify at most one publish destination. The destinationCount check increments for each of S3, GCS, Vault (and others) that are non-empty, and errors when more than one destination is set in the same rule, since sops can only upload to one destination per rule.

Source

Thrown at config/config.go:548

	if dRule == nil {
		return nil, fmt.Errorf("error loading config: no matching destination found in config")
	}

	var dest publish.Destination
	destinationCount := 0
	if dRule.S3Bucket != "" {
		destinationCount++
	}
	if dRule.GCSBucket != "" {
		destinationCount++
	}
	if dRule.VaultPath != "" {
		destinationCount++
	}

	if destinationCount > 1 {
		return nil, fmt.Errorf("error loading config: more than one destinations were found in a single destination rule, you can only use one per rule")
	}
	if dRule.S3Bucket != "" {
		dest = publish.NewS3Destination(dRule.S3Bucket, dRule.S3Prefix)
	}
	if dRule.GCSBucket != "" {
		dest = publish.NewGCSDestination(dRule.GCSBucket, dRule.GCSPrefix)
	}
	if dRule.VaultPath != "" {
		dest = publish.NewVaultDestination(dRule.VaultAddress, dRule.VaultPath, dRule.VaultKVMountName, dRule.VaultKVVersion)
	}

	config, err := configFromRule(rule, kmsEncryptionContext)
	if err != nil {
		return nil, err
	}
	config.Destination = dest
	config.OmitExtensions = dRule.OmitExtensions

View on GitHub (pinned to 13442bb981)

Solutions

  1. Split the rule into multiple destination_rules entries, each with exactly one destination and its own path_regex
  2. Remove the extra destination key from the rule, keeping only the intended one
  3. If both destinations are genuinely needed, run sops twice with different configs or publish manually afterwards

Example fix

# before
- path_regex: '.*'
  s3_bucket: 'bkt'
  gcs_bucket: 'gsbkt'
# after
- path_regex: '.*\.s3\.'
  s3_bucket: 'bkt'
- path_regex: '.*\.gcs\.'
  gcs_bucket: 'gsbkt'
Defensive patterns

Strategy: validation

Validate before calling

destKeys := []string{"s3_bucket","gcs_bucket","vault_path"}
count := 0
for _, k := range destKeys {
    if v, _ := rule[k].(string); v != "" { count++ }
}
if count > 1 {
    return errors.New("destination rule sets multiple destinations")
}

Try / catch

cfg, err := configFromRule(rule, ctx)
if err != nil && strings.Contains(err.Error(), "more than one destinations") {
    return fmt.Errorf("split the destination rule into one rule per destination: %w", err)
}

Prevention

When it happens

Trigger: One destination_rules entry sets two or more destination keys, e.g. both s3_bucket and gcs_bucket on the same rule.

Common situations: Merging destination rules for multi-cloud setups into a single entry; adding a new destination key to an existing rule instead of creating a second rule.

Related errors


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/a459f5b2e00a9c44. Report an issue: GitHub.