Billionmail/BillionMail · error

failed to change DKIM file permissions: %v

Error message

failed to change DKIM file permissions: %v

What it means

After writing the signing config, the function walks the dkim directory and chmods .private/.pub key files to 0644. This error wraps any failure from filepath.Walk or os.Chmod during that permission pass.

Source

Thrown at core/internal/service/domains/domains.go:990

	if err != nil {
		return fmt.Errorf("failed to write DKIM signing config: %v", err)
	}

	// 5. Ensure correct file permissions
	err = filepath.Walk(filepath.Join(public.AbsPath(consts.RSPAMD_LIB_PATH), "dkim"), func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return os.Chmod(path, 0755)
		}
		if strings.HasSuffix(path, ".private") || strings.HasSuffix(path, ".pub") {
			return os.Chmod(path, 0644)
		}
		return nil
	})
	if err != nil {
		return fmt.Errorf("failed to change DKIM file permissions: %v", err)
	}

	// 6. Restart rspamd service
	dk, err := docker.NewDockerAPI()
	if err != nil {
		return fmt.Errorf("failed to connect to Docker API: %v", err)
	}
	defer dk.Close()

	err = dk.RestartContainerByName(ctx, consts.SERVICES.Rspamd)
	if err != nil {
		return fmt.Errorf("failed to restart rspamd container: %v", err)
	}

	return nil
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Check the wrapped %v error to identify the failing path, then chown/chmod that file manually
  2. Ensure the dkim keys directory is on a Linux filesystem that supports chmod
  3. Run the process as a user that owns the DKIM key files
  4. Verify the dkim dir under RSPAMD_LIB_PATH exists before running repair

Example fix

// before
return os.Chmod(path, 0644)
// after
if err := os.Chmod(path, 0644); err != nil {
	return fmt.Errorf("chmod %s: %w", path, err)
}
Defensive patterns

Strategy: validation

Validate before calling

dkimDir := filepath.Join(public.AbsPath(consts.RSPAMD_LIB_PATH), "dkim")
if fi, err := os.Stat(dkimDir); err != nil || !fi.IsDir() {
	return fmt.Errorf("dkim key dir missing: %s", dkimDir)
}

Try / catch

if err := RepairDKIMSigningConfig(ctx); err != nil && strings.Contains(err.Error(), "failed to change DKIM file permissions") {
	log.Printf("fix ownership of dkim keys: %v", err)
}

Prevention

When it happens

Trigger: filepath.Walk fails on a path (I/O error, symlink issues) or os.Chmod on a .private/.pub file is denied; the dkim directory under RSPAMD_LIB_PATH is missing or unreadable.

Common situations: DKIM keys stored on a read-only or FAT/exFAT mount that ignores chmod; process lacking ownership of key files after a container image update; dkim dir deleted or re-created by another job mid-run.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/50cf728d1f8afecc. Report an issue: GitHub.