kgretzky/evilginx2 · error

login: missing `domain` field

Error message

login: missing `domain` field

What it means

Phishlet validation requires the `login` section to declare a `domain` field, which tells Evilginx which proxy host the login form belongs to. When the parsed `login.domain` key is absent (nil) from the YAML, loading aborts with this message.

Source

Thrown at core/phishlet.go:636

	p.password.search, err = regexp.Compile(p.paramVal(*fp.Credentials.Password.Search))
	if err != nil {
		return fmt.Errorf("credentials: %v", err)
	}

	p.username.tp = fp.Credentials.Username.Type
	if p.username.tp == "" {
		p.username.tp = "post"
	}
	p.password.tp = fp.Credentials.Password.Type
	if p.password.tp == "" {
		p.password.tp = "post"
	}
	p.username.key_s = p.paramVal(*fp.Credentials.Username.Key)
	p.password.key_s = p.paramVal(*fp.Credentials.Password.Key)

	if fp.LoginItem.Domain == nil {
		return fmt.Errorf("login: missing `domain` field")
	}
	if fp.LoginItem.Path == nil {
		return fmt.Errorf("login: missing `path` field")
	}
	p.login.domain = p.paramVal(*fp.LoginItem.Domain)
	if p.login.domain == "" {
		return fmt.Errorf("login: `domain` field cannot be empty")
	}
	login_domain_ok := false
	for _, h := range p.proxyHosts {
		var check_host string
		if h.orig_subdomain != "" {
			check_host = h.orig_subdomain + "."
		}
		check_host += h.domain
		if strings.ToLower(check_host) == strings.ToLower(p.login.domain) {
			login_domain_ok = true
			break

View on GitHub (pinned to 4c0988a1d9)

Solutions

  1. Add a `domain:` key under the `login:` section with one of the hostnames from `proxy_hosts` (orig_subdomain + "." + domain).
  2. Compare with a working phishlet for the same site and copy the login block structure.
  3. Ensure the file targets the phishlet format version your build expects (2.x+ requires login.domain).
  4. Reload the phishlet after editing; validation runs in order, so fix later login errors next.

Example fix

// before
login:
  path: /login
// after
login:
  domain: accounts.example.com
  path: /login
Defensive patterns

Strategy: validation

Validate before calling

if pl.Login == nil || pl.Login.Domain == nil || pl.Login.Domain == "" {
    return errors.New("phishlet: login.domain is required and must match a proxy_hosts hostname")
}

Type guard

func loginDomainSet(l *LoginItem) bool { return l != nil && l.Domain != nil && *l.Domain != "" }

Try / catch

if err := pl.Load(cfg); err != nil {
    if strings.Contains(err.Error(), "missing `domain`") {
        log.Printf("phishlet %s needs login.domain (e.g. accounts.example.com)", pl.Name)
    }
}

Prevention

When it happens

Trigger: Loading a phishlet YAML whose `login:` block omits the `domain:` key entirely, e.g. only `login: { username: ..., password: ... }` or a completely missing `login` mapping for the relevant subfilter.

Common situations: Older phishlet formats (pre-2.x) that used a different login schema; hand-trimming phishlets and accidentally deleting the `domain` line; copy-pasting only part of a phishlet.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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