getsops/sops · error

Could not unmarshal config file

Error message

Could not unmarshal config file: %s

What it means

configFile.load unmarshals the raw bytes of the sops config file with yaml.Unmarshal into the internal configFile struct; any YAML syntax error or type mismatch is wrapped in this error. The message includes the underlying yaml error text with position details.

Solutions

  1. Fix the YAML syntax at the line/column reported in the wrapped error text
  2. Replace tabs with spaces and ensure consistent indentation
  3. Quote strings containing special YAML characters (`:*{[],#&`)
  4. Validate the file with a YAML linter or `sops edit`/dry-run before committing

Example fix

# before
creation_rules:
	- path_regex: *.png   # tab + unquoted glob: invalid YAML
# after
creation_rules:
  - path_regex: ".*\.png"
Defensive patterns

Strategy: validation

Validate before calling

// lint the config before running sops
import "gopkg.in/yaml.v3"
func yamlOK(b []byte) bool {
	var v map[string]interface{}
	return yaml.Unmarshal(b, &v) == nil
}
// usage: if !yamlOK(configBytes) { run 'yamllint .sops.yaml' and fix }

Try / catch

cfg, err := config.LoadCreationRuleForFile(".sops.yaml", "secrets.yaml", time.Now())
if err != nil && strings.HasPrefix(err.Error(), "Could not unmarshal config file") {
	return fmt.Errorf("invalid YAML in .sops.yaml — fix syntax at the reported line: %w", err)
}

Prevention

When it happens

Trigger: Calling load (indirectly via loadConfigFile/parseConfigFile) on a `.sops.yaml` containing invalid YAML: bad indentation, tabs, unclosed quotes, duplicate keys, or a field of the wrong type (e.g. creation_rules as a string instead of a list).

Common situations: Hand-editing .sops.yaml with tab indentation, missing space after a colon (`creation_rules:- ...`), copy-paste artifacts, forgetting to quote strings containing special characters like `*` or `:`.

Related errors


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

Appendix: source

Thrown at config/config.go:273

	case []string:
		return v, nil
	default:
		return nil, fmt.Errorf("invalid %s key configuration: expected string, []string, or nil, got %T", fieldName, field)
	}
}

func NewStoresConfig() *StoresConfig {
	storesConfig := &StoresConfig{}
	storesConfig.JSON.Indent = -1
	storesConfig.JSONBinary.Indent = -1
	return storesConfig
}

// Load loads a sops config file into a temporary struct
func (f *configFile) load(bytes []byte) error {
	err := yaml.Unmarshal(bytes, f)
	if err != nil {
		return fmt.Errorf("Could not unmarshal config file: %s", err)
	}
	return nil
}

// Config is the configuration for a given SOPS file
type Config struct {
	KeyGroups               []sops.KeyGroup
	ShamirThreshold         int
	UnencryptedSuffix       string
	EncryptedSuffix         string
	UnencryptedRegex        string
	EncryptedRegex          string
	UnencryptedCommentRegex string
	EncryptedCommentRegex   string
	MACOnlyEncrypted        bool
	Destination             publish.Destination
	OmitExtensions          bool
}

View on GitHub (pinned to 13442bb981)