{"record":{"id":"50cf728d1f8afecc","repo":"Billionmail/BillionMail","slug":"failed-to-change-dkim-file-permissions-v","errorCode":null,"errorMessage":"failed to change DKIM file permissions: %v","messagePattern":"failed to change DKIM file permissions: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/domains/domains.go","lineNumber":990,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write DKIM signing config: %v\", err)\n\t}\n\n\t// 5. Ensure correct file permissions\n\terr = filepath.Walk(filepath.Join(public.AbsPath(consts.RSPAMD_LIB_PATH), \"dkim\"), func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif info.IsDir() {\n\t\t\treturn os.Chmod(path, 0755)\n\t\t}\n\t\tif strings.HasSuffix(path, \".private\") || strings.HasSuffix(path, \".pub\") {\n\t\t\treturn os.Chmod(path, 0644)\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to change DKIM file permissions: %v\", err)\n\t}\n\n\t// 6. Restart rspamd service\n\tdk, err := docker.NewDockerAPI()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to connect to Docker API: %v\", err)\n\t}\n\tdefer dk.Close()\n\n\terr = dk.RestartContainerByName(ctx, consts.SERVICES.Rspamd)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to restart rspamd container: %v\", err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":972,"sourceCodeEnd":1007,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/domains/domains.go#L972-L1007","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the wrapped %v error to identify the failing path, then chown/chmod that file manually","Ensure the dkim keys directory is on a Linux filesystem that supports chmod","Run the process as a user that owns the DKIM key files","Verify the dkim dir under RSPAMD_LIB_PATH exists before running repair"],"exampleFix":"// before\nreturn os.Chmod(path, 0644)\n// after\nif err := os.Chmod(path, 0644); err != nil {\n\treturn fmt.Errorf(\"chmod %s: %w\", path, err)\n}","handlingStrategy":"validation","validationCode":"dkimDir := filepath.Join(public.AbsPath(consts.RSPAMD_LIB_PATH), \"dkim\")\nif fi, err := os.Stat(dkimDir); err != nil || !fi.IsDir() {\n\treturn fmt.Errorf(\"dkim key dir missing: %s\", dkimDir)\n}","typeGuard":null,"tryCatchPattern":"if err := RepairDKIMSigningConfig(ctx); err != nil && strings.Contains(err.Error(), \"failed to change DKIM file permissions\") {\n\tlog.Printf(\"fix ownership of dkim keys: %v\", err)\n}","preventionTips":["Keep DKIM keys on a filesystem supporting chmod (ext4, not exFAT)","Ensure the process user owns the dkim key files","Re-apply ownership after container image updates","Pre-set correct permissions at key-generation time"],"tags":["filesystem","permissions","dkim","chmod"],"backgroundTag":"file-permission-denied","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}