kgretzky/evilginx2 · error

phishlet '%s' already exists

Error message

phishlet '%s' already exists

What it means

CreatePhishlet (child creation from a parent site) throws this when a phishlet with the requested new name already exists in the config. The check is GetPhishlet(site) succeeding, meaning the name is taken, so creation is aborted to avoid overwriting existing phishlet configuration.

Source

Thrown at core/config.go:571

		}
	}
	return false
}

func (c *Config) AddPhishlet(site string, pl *Phishlet) {
	c.phishletNames = append(c.phishletNames, site)
	c.phishlets[site] = pl
	c.VerifyPhishlets()
}

func (c *Config) AddSubPhishlet(site string, parent_site string, customParams map[string]string) error {
	pl, err := c.GetPhishlet(parent_site)
	if err != nil {
		return err
	}
	_, err = c.GetPhishlet(site)
	if err == nil {
		return fmt.Errorf("phishlet '%s' already exists", site)
	}
	sub_pl, err := NewPhishlet(site, pl.Path, &customParams, c)
	if err != nil {
		return err
	}
	sub_pl.ParentName = parent_site

	c.phishletNames = append(c.phishletNames, site)
	c.phishlets[site] = sub_pl
	c.VerifyPhishlets()

	return nil
}

func (c *Config) DeleteSubPhishlet(site string) error {
	pl, err := c.GetPhishlet(site)
	if err != nil {
		return err

View on GitHub (pinned to 4c0988a1d9)

Solutions

  1. Choose a different, unique child phishlet name for the create call
  2. If the existing phishlet should be replaced, delete it first (phishlets delete <name>) then create again
  3. If it already exists with the right params, skip creation and just enable/configure the existing phishlet
  4. Make scripts idempotent: check GetPhishlet/list output before calling create

Example fix

// console
// before
phishlets create o365-corp o365 hostname corp.example.com   # second run: already exists
// after
phishlets delete o365-corp
phishlets create o365-corp o365 hostname corp.example.com
Defensive patterns

Strategy: try-catch

Validate before calling

// before creating
if _, err := c.GetPhishlet(site); err == nil {
    return fmt.Errorf("phishlet %s exists; pick another name or delete it first", site)
}
c.CreatePhishlet(site, parentSite, params, true)

Try / catch

err := c.CreatePhishlet(site, parentSite, customParams, true)
if err != nil {
    if strings.Contains(err.Error(), "already exists") {
        log.Printf("phishlet %s exists — reuse it or 'phishlets delete %s' first", site, site)
        return nil // treat as success in idempotent scripts
    }
    return err
}

Prevention

When it happens

Trigger: Calling phishlet creation with a site name that already exists — e.g. running 'phishlets create mysite o365 ...' twice, or re-running an idempotent-looking setup script that doesn't check for prior creation, or colliding with a loaded template phishlet of the same name.

Common situations: Re-running provisioning scripts after a partial failure; two operators creating the same child name; name collision with a built-in/template phishlet; migration scripts re-importing phishlet definitions.

Related errors


AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05). Data as JSON: /api/errors/a52beee49329c360. Report an issue: GitHub.