projectdiscovery/nuclei · error

could not resolve to a DN

Error message

could not resolve %q to a DN

What it means

DCSync's target must resolve to a distinguished name. If the argument does not already start with CN=, the code cracks it twice: first as an NT4 account name (DOMAIN\\user) and then as a SID. If both DsCrackNames attempts fail or return an empty name, the target does not exist (or cannot be cracked by this principal) and this error is returned.

Solutions

  1. Pass the exact sAMAccountName, e.g. DCSync('krbtgt')
  2. Or pass the full DN directly: DCSync('CN=Administrator,CN=Users,DC=acme,DC=local')
  3. Or pass the objectSid: DCSync('S-1-5-21-...-500')
  4. Verify the account exists with an LDAP search before syncing

Example fix

// before
const s = c.DCSync('administrator@acme.local'); // UPN form cannot be cracked

// after
const s = c.DCSync('Administrator');
Defensive patterns

Strategy: validation

Validate before calling

// Resolve or verify the target before DCSync
if !strings.HasPrefix(target, "CN=") && !strings.HasPrefix(target, "S-1-") {
    // will be cracked as DOMAIN\\sAMAccountName — confirm it exists via LDAP first
    if !samExists(dc, domain, target) {
        return fmt.Errorf("target %q does not exist", target)
    }
}

Type guard

func isResolvableTarget(t string) bool {
    return strings.HasPrefix(t, "CN=") || strings.HasPrefix(t, "cn=") ||
        strings.HasPrefix(t, "S-1-") || !strings.Contains(t, "@")
}

Try / catch

secret, err := c.DCSync(target)
if err != nil && strings.Contains(err.Error(), "could not resolve") {
    // account name wrong or UPN form used: retry with sAMAccountName or SID
    secret, err = c.DCSync(samFromSid(sid))
}

Prevention

When it happens

Trigger: DCSync('Admistrator') with a typo; DCSync('user@acme.local') — a UPN is neither the NT4 sAMAccountName form nor a SID; account lives in another trusted domain; caller lacks rights to crack names.

Common situations: UPN passed where sAMAccountName is expected; usernames harvested from email addresses; deleted or renamed accounts.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/9e9e98eea175c320. Report an issue: GitHub.

Appendix: source

Thrown at pkg/js/libs/secretsdump/secretsdump.go:156

	dcInfo, err := gpdrs.DsDomainControllerInfo(rpc, bind.Handle, c.Domain)
	if err != nil {
		return nil, fmt.Errorf("ds dc info: %w", err)
	}

	domainDN, err := gpdrs.GetDomainDN(rpc, bind.Handle, c.Domain)
	if err != nil {
		return nil, fmt.Errorf("ds domain dn: %w", err)
	}

	// Resolve target -> DN if it doesn't already look like one.
	userDN := target
	if len(target) < 3 || (target[:3] != "CN=" && target[:3] != "cn=") {
		cracked, err := gpdrs.DsCrackNames(rpc, bind.Handle, 7 /* DS_NT4_ACCOUNT_NAME */, 1 /* DS_FQDN_1779_NAME */, []string{c.Domain + "\\" + target})
		if err != nil || len(cracked) == 0 || cracked[0].Name == "" {
			cracked, err = gpdrs.DsCrackNames(rpc, bind.Handle, 11 /* DS_UNIQUE_ID_NAME (SID) */, 1, []string{target})
			if err != nil || len(cracked) == 0 || cracked[0].Name == "" {
				return nil, fmt.Errorf("could not resolve %q to a DN", target)
			}
		}
		userDN = cracked[0].Name
	}

	res, err := gpdrs.DsGetNCChanges(rpc, bind.Handle, domainDN, userDN, dcInfo.NtdsDsaObjectGuid, rpc.GetSessionKey())
	if err != nil {
		return nil, fmt.Errorf("DsGetNCChanges: %w", err)
	}
	if len(res.Objects) == 0 {
		return nil, fmt.Errorf("DsGetNCChanges returned no objects")
	}
	o := res.Objects[0]
	out := &Secret{
		SAMAccountName:     o.SAMAccountName,
		DistinguishedName:  o.DN,
		RID:                o.RID,
		NTHash:             hex.EncodeToString(o.NTHash),

View on GitHub (pinned to 265b3a3dec)