kgretzky/evilginx2 · error
failed to list certificates in directory
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.
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
- auth_tokens: 'domain' not found for body auth token
- auth_tokens: 'domain' not found for cookie auth token
- auth_tokens: invalid token type
- auth_tokens: 'keys' not found for cookie auth token
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/1b08e989d30e8324.
Report an issue: GitHub.
Appendix: 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)