{"record":{"id":"107b0c5ce8d2f782","repo":"kgretzky/evilginx2","slug":"failed-to-list-certificate-directory-s-v","errorCode":null,"errorMessage":"failed to list certificate directory '%s': %v","messagePattern":"failed to list certificate directory '(.+?)': (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/certdb.go","lineNumber":186,"sourceCode":"\tcancel()\n\treturn err\n}\n\nfunc (o *CertDb) setUnmanagedSync(verbose bool) error {\n\tsitesDir := filepath.Join(o.cache_dir, \"sites\")\n\n\tfiles, err := os.ReadDir(sitesDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to list certificates in directory '%s': %v\", sitesDir, err)\n\t}\n\n\tfor _, f := range files {\n\t\tif f.IsDir() {\n\t\t\tcertDir := filepath.Join(sitesDir, f.Name())\n\n\t\t\tcertFiles, err := os.ReadDir(certDir)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to list certificate directory '%s': %v\", certDir, err)\n\t\t\t}\n\n\t\t\tvar certPath, keyPath string\n\n\t\t\tvar pemCnt, crtCnt, keyCnt int\n\t\t\tfor _, cf := range certFiles {\n\t\t\t\t//log.Debug(\"%s\", cf.Name())\n\t\t\t\tif !cf.IsDir() {\n\t\t\t\t\tswitch strings.ToLower(filepath.Ext(cf.Name())) {\n\t\t\t\t\tcase \".pem\":\n\t\t\t\t\t\tpemCnt += 1\n\t\t\t\t\t\tif certPath == \"\" {\n\t\t\t\t\t\t\tcertPath = filepath.Join(certDir, cf.Name())\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif cf.Name() == \"fullchain.pem\" {\n\t\t\t\t\t\t\tcertPath = filepath.Join(certDir, cf.Name())\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif cf.Name() == \"privkey.pem\" {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/certdb.go#L168-L204","documentation":"setUnmanagedSync throws this when os.ReadDir fails on an individual per-site certificate directory inside cache_dir/sites. The parent sites/ directory was readable, but at least one site subdirectory could not be listed, aborting the whole sync loop.","triggerScenarios":"A site directory exists in sites/ but ReadDir fails on it: permission mismatch (dir created as root, process runs as another user), the entry is a broken symlink to a directory, or the directory was removed concurrently mid-iteration.","commonSituations":"Mixed-permission caches after running the tool with sudo once; cleanup scripts partially deleting site dirs; stale site folders left after cache migration; NFS/network filesystem hiccups.","solutions":["Fix ownership/permissions on the offending site directory (chown -R / chmod u+rx)","Remove stale or broken site directories from sites/ so the scan can complete","Run the tool as the user that owns the cache","Recreate the sites directory structure and re-sync certificates"],"exampleFix":"// before\nls -l ~/.evilginx/cache/sites/  # drwx------ root root mysite\n// after\nsudo chown -R $USER ~/.evilginx/cache/sites && chmod -R u+rwX ~/.evilginx/cache/sites","handlingStrategy":"validation","validationCode":"sitesDir := filepath.Join(cacheDir, \"sites\")\nentries, err := os.ReadDir(sitesDir)\nif err == nil {\n    for _, e := range entries {\n        if e.IsDir() {\n            if _, err := os.ReadDir(filepath.Join(sitesDir, e.Name())); err != nil {\n                log.Printf(\"unreadable site dir %s: %v — fix before sync\", e.Name(), err)\n            }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := db.setUnmanagedSync(true); err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to list certificate directory\") {\n        // extract dir from message, chown/chmod or delete the stale dir, retry\n        log.Printf(\"fix permissions on the named site dir, then retry: %v\", err)\n    }\n}","preventionTips":["chmod u+rwX your cache tree after any sudo run","Delete broken symlinks/stale site dirs under sites/","Keep cache ownership consistent with the service user","Avoid network filesystems for the certificate cache"],"tags":["filesystem","certificate","permissions"],"backgroundTag":"directory-not-found","analyzedSha":"4c0988a1d9db4d172a185e979a38bfd0efdb5830","analyzedAt":"2026-09-05T19:23:07.238Z","contentChangedAt":"2026-09-05T19:23:07.238Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}