kgretzky/evilginx2 · error
failed to list certificate directory '%s': %v
Error message
failed to list certificate directory '%s': %v
What it means
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.
Source
Thrown at core/certdb.go:186
cancel()
return err
}
func (o *CertDb) setUnmanagedSync(verbose bool) error {
sitesDir := filepath.Join(o.cache_dir, "sites")
files, err := os.ReadDir(sitesDir)
if err != nil {
return fmt.Errorf("failed to list certificates in directory '%s': %v", sitesDir, err)
}
for _, f := range files {
if f.IsDir() {
certDir := filepath.Join(sitesDir, f.Name())
certFiles, err := os.ReadDir(certDir)
if err != nil {
return fmt.Errorf("failed to list certificate directory '%s': %v", certDir, err)
}
var certPath, keyPath string
var pemCnt, crtCnt, keyCnt int
for _, cf := range certFiles {
//log.Debug("%s", cf.Name())
if !cf.IsDir() {
switch strings.ToLower(filepath.Ext(cf.Name())) {
case ".pem":
pemCnt += 1
if certPath == "" {
certPath = filepath.Join(certDir, cf.Name())
}
if cf.Name() == "fullchain.pem" {
certPath = filepath.Join(certDir, cf.Name())
}
if cf.Name() == "privkey.pem" {View on GitHub (pinned to 4c0988a1d9)
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
Example fix
// before ls -l ~/.evilginx/cache/sites/ # drwx------ root root mysite // after sudo chown -R $USER ~/.evilginx/cache/sites && chmod -R u+rwX ~/.evilginx/cache/sites
Defensive patterns
Strategy: validation
Validate before calling
sitesDir := filepath.Join(cacheDir, "sites")
entries, err := os.ReadDir(sitesDir)
if err == nil {
for _, e := range entries {
if e.IsDir() {
if _, err := os.ReadDir(filepath.Join(sitesDir, e.Name())); err != nil {
log.Printf("unreadable site dir %s: %v — fix before sync", e.Name(), err)
}
}
}
} Try / catch
if err := db.setUnmanagedSync(true); err != nil {
if strings.HasPrefix(err.Error(), "failed to list certificate directory") {
// extract dir from message, chown/chmod or delete the stale dir, retry
log.Printf("fix permissions on the named site dir, then retry: %v", err)
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to list certificates in directory '%s': %v
- private key generation failed
- private key is corrupted
- failed to get TLS certificate for: %s:%d error: %s
- edit: redirector directory does not exist: %s
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/107b0c5ce8d2f782.
Report an issue: GitHub.