kgretzky/evilginx2 · error
login: `domain` must contain a value of one of the hostnames
Error message
login: `domain` must contain a value of one of the hostnames (`orig_subdomain` + `domain`) defined in `proxy_hosts` section
What it means
The `login.domain` value must match (case-insensitively) one of the hostnames derived from the `proxy_hosts` section (`orig_subdomain` + "." + `domain`, optionally with a leading `*.` check). If it does not correspond to any proxy host, loading aborts because Evilginx could not route the login page through any proxied host.
Source
Thrown at core/phishlet.go:658
}
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
}
}
if !login_domain_ok {
return fmt.Errorf("login: `domain` must contain a value of one of the hostnames (`orig_subdomain` + `domain`) defined in `proxy_hosts` section")
}
p.login.path = p.paramVal(*fp.LoginItem.Path)
if p.login.path == "" {
p.login.path = "/"
}
if p.login.path[0] != '/' {
p.login.path = "/" + p.login.path
}
if fp.Credentials.Custom != nil {
for _, cp := range *fp.Credentials.Custom {
var err error
if cp.Key == nil {
return fmt.Errorf("credentials: missing custom `key` field")
}
if cp.Search == nil {
return fmt.Errorf("credentials: missing custom `search` field")View on GitHub (pinned to 4c0988a1d9)
Solutions
- Set `login.domain` to exactly `orig_sub + "." + domain` as written in one of the proxy_hosts entries.
- If the login happens on a different host, add a matching proxy_hosts entry for that host.
- Do not use the phishing (phish_sub) hostname in login.domain — it must be the original one.
- Re-check for typos and case; matching is case-insensitive but text must otherwise be identical.
Example fix
// before
proxy_hosts:
- phish_sub: acct
orig_sub: accounts
domain: example.com
login:
domain: login.example.com
// after
login:
domain: accounts.example.com Defensive patterns
Strategy: validation
Validate before calling
d := strings.ToLower(pl.Login.Domain)
ok := false
for _, h := range pl.ProxyHosts {
if strings.ToLower(h.OrigSubdomain+"."+h.Domain) == d { ok = true; break }
}
if !ok {
return fmt.Errorf("login.domain %q not found in proxy_hosts", pl.Login.Domain)
} Type guard
func loginDomainMatches(l *LoginItem, hosts []ProxyHost) bool {
if l == nil || l.Domain == nil { return false }
for _, h := range hosts {
if strings.EqualFold(h.OrigSubdomain+"."+h.Domain, *l.Domain) { return true }
}
return false
} Try / catch
if err := pl.Load(cfg); err != nil {
if strings.Contains(err.Error(), "must contain a value of one of the hostnames") {
log.Printf("login.domain must equal orig_sub+'.'+domain of a proxy_host in %s", pl.Name)
}
} Prevention
- Use the original hostname (orig_subdomain.domain), never the phishing subdomain.
- Update login.domain whenever you edit proxy_hosts.
- Add the login host as its own proxy_hosts entry if the form lives on another subdomain.
- Run an automated consistency check across phishlets.
When it happens
Trigger: `login.domain` set to a hostname like `login.example.com` while proxy_hosts only defines `accounts.example.com`; or a typo/top-level mismatch (e.g. `example.org` vs `example.com`); or omitting the subdomain when proxy_hosts expects `orig_subdomain.domain`.
Common situations: Renaming proxy_hosts after writing the login block; copying a phishlet for one site and editing only the domain; mixing up `phish_sub` (your phishing subdomain) with `orig_sub` (must be the orig one).
Related errors
- login: `domain` field cannot be empty
- enabling phishlet '%s' requires its hostname to be set up
- no hostname set for phishlet '%s'
- phishlet '%s' is a template - you have to 'create' child phi
- phishlet '%s' already exists
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/ae02aaac906b1620.
Report an issue: GitHub.