kgretzky/evilginx2 · error
failed to list certificates in directory '%s': %v
Error message
failed to list certificates in directory '%s': %v
What it means
setUnmanagedSync scans the 'sites' subdirectory of the certificate cache to discover per-site certificate directories, and throws this when os.ReadDir on that directory fails. This typically means the cache directory structure is missing or unreadable, so unmanaged certificate synchronization cannot proceed.
Source
Thrown at core/certdb.go:177
if err != nil {
return err
}
return nil
}
func (o *CertDb) setManagedSync(hosts []string, t time.Duration) error {
ctx, cancel := context.WithTimeout(context.Background(), t)
err := o.magic.ManageSync(ctx, hosts)
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())) {View on GitHub (pinned to 4c0988a1d9)
Solutions
- Ensure the cache_dir and its sites/ subdirectory exist and are readable (mkdir -p, chmod)
- Fix cache_dir configuration to point to the correct directory
- Check volume is mounted and writable by the process user
- Reinitialize the cache directory and let the tool recreate the structure
Example fix
// before -o c2.domain cache_dir=/mnt/missing/certs // after mkdir -p /var/lib/evilginx/cache/sites && chmod 700 /var/lib/evilginx/cache # then start with cache_dir=/var/lib/evilginx/cache
Defensive patterns
Strategy: validation
Validate before calling
sitesDir := filepath.Join(cacheDir, "sites")
if st, err := os.Stat(sitesDir); err != nil || !st.IsDir() {
os.MkdirAll(sitesDir, 0700)
} Try / catch
if err := db.setUnmanagedSync(true); err != nil {
if strings.HasPrefix(err.Error(), "failed to list certificates in directory") {
os.MkdirAll(filepath.Join(cacheDir, "sites"), 0700)
err = db.setUnmanagedSync(true)
}
if err != nil { log.Fatal(err) }
} Prevention
- Create cache_dir/sites before first run
- Run the process as the user owning the cache; avoid mixing root and user runs
- Ensure the volume holding cache_dir is mounted and writable
- Point cache_dir config at a directory, never a file
When it happens
Trigger: os.ReadDir(sitesDir) returns an error: cache_dir/sites was deleted, cache_dir points to a nonexistent path, wrong permissions on the directory, or cache_dir configured to a file rather than a directory.
Common situations: First run with a wiped cache before directory creation; cache_dir on a read-only or unmounted volume; running as a different user after generating certs as root (permission denied); typo in cache_dir configuration.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to list certificate directory '%s': %v
- private key generation failed
- private key is corrupted
- failed to get TLS certificate for: %s:%d error: %s
- enabling phishlet '%s' requires its hostname to be set up
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/1b08e989d30e8324.
Report an issue: GitHub.