AdguardTeam/AdGuardHome · critical

writing new config: %w

Error message

writing new config: %w

What it means

After upgrading the config to a newer schema, AdGuard Home failed to write the migrated config file to disk. The wrapped error is a filesystem error from maybe.WriteFile.

Source

Thrown at internal/home/config.go:679

		DataDir:    filepath.Join(workDir, dataDir),
	})

	var upgraded bool
	config.fileData, upgraded, err = migrator.Migrate(
		ctx,
		config.fileData,
		configmigrate.LastSchemaVersion,
	)
	if err != nil {
		// Don't wrap the error, because it's informative enough as is.
		return err
	} else if upgraded {
		confPath = configFilePath(ctx, l, workDir, confPath)
		l.DebugContext(ctx, "writing config file after config upgrade", "path", confPath)

		err = maybe.WriteFile(confPath, config.fileData, aghos.DefaultPermFile)
		if err != nil {
			return fmt.Errorf("writing new config: %w", err)
		}
	}

	err = yaml.Unmarshal(config.fileData, &config)
	if err != nil {
		// Don't wrap the error since it's informative enough as is.
		return err
	}

	err = validateConfig(ctx, l, config.fileData)
	if err != nil {
		return err
	}

	if config.DNS.UpstreamTimeout == 0 {
		config.DNS.UpstreamTimeout = timeutil.Duration(dnsforward.DefaultTimeout)
	}

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Check the wrapped error for the OS-level cause (permission denied, no space, etc.)
  2. Grant write permission on the config directory to the running user (chown/chmod)
  3. Free disk space or remount the filesystem read-write
  4. Verify the -w work-dir / config path is correct for how the service runs
Defensive patterns

Strategy: fallback

Validate before calling

// Preflight: ensure config dir is writable before upgrading
if f, err := os.CreateTemp(confDir, ".w"); err != nil { return err } else { f.Close(); os.Remove(f.Name()) }

Try / catch

// On write failure, keep serving with in-memory config and alert
if err != nil { log.Error(...); continueWithOldConfig() }

Prevention

When it happens

Trigger: Startup detects the config needs upgrading, writes the new version to confPath, and the OS rejects the write (permissions, missing/invalid directory, disk full, read-only filesystem).

Common situations: Running the binary as a non-root user without write access to the config dir, config path pointing to a read-only mount/container, full disk, SELinux/AppArmor denials.

Related errors


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