AdguardTeam/AdGuardHome · error

parsing config file for upgrade

Error message

parsing config file for upgrade: %w

What it means

Migrate fails to YAML-parse the configuration file body before upgrading its schema. The yaml.Unmarshal error is wrapped, so syntax problems (bad indentation, tabs, invalid scalars) are reported with position info.

Solutions

  1. Run a YAML linter or `yaml.Unmarshal` on the file to locate the syntax error reported in the wrapped cause
  2. Restore the config from backup or re-download it if corrupted
  3. Fix indentation (spaces, not tabs) and quoting, then retry Migrate

Example fix

# before (tabs)
users:
	- name: admin

# after (spaces)
users:
  - name: admin
Defensive patterns

Strategy: validation

Validate before calling

var probe map[string]any
if err := yaml.Unmarshal(body, &probe); err != nil { /* fix YAML before Migrate */ }

Try / catch

if _, _, err := configmigrate.Migrate(ctx, body, target); err != nil && strings.Contains(err.Error(), "parsing config file for upgrade") { /* report syntax error with position from wrapped cause */ }

Prevention

When it happens

Trigger: Calling Migrate with a body that is not valid YAML, e.g. a tab-indented file, unbalanced quotes, or a truncated/corrupted config.

Common situations: Hand-edited YAML.yaml with tabs or copy-paste artifacts, a config file corrupted by an interrupted write, feeding JSON or encrypted data to the migrator.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/f3fe50e334bdfff1. Report an issue: GitHub.

Appendix: source

Thrown at internal/configmigrate/migrator.go:53

		logger:     c.Logger,
		workingDir: c.WorkingDir,
		dataDir:    c.DataDir,
	}
}

// Migrate preforms necessary upgrade operations to upgrade file to target
// schema version, if needed.  It returns the body of the upgraded config file,
// whether the file was upgraded, and an error, if any.  If upgraded is false,
// the body is the same as the input.
func (m *Migrator) Migrate(
	ctx context.Context,
	body []byte,
	target uint,
) (newBody []byte, upgraded bool, err error) {
	diskConf := yobj{}
	err = yaml.Unmarshal(body, &diskConf)
	if err != nil {
		return body, false, fmt.Errorf("parsing config file for upgrade: %w", err)
	}

	currentInt, _, err := fieldVal[int](diskConf, "schema_version")
	if err != nil {
		// Don't wrap the error, since it's informative enough as is.
		return body, false, err
	}

	current := uint(currentInt)
	m.logger.DebugContext(ctx, "got", "schema_version", current)

	if err = validateVersion(current, target); err != nil {
		// Don't wrap the error, since it's informative enough as is.
		return body, false, err
	} else if current == target {
		return body, false, nil
	}

View on GitHub (pinned to b41aefbe51)