projectdiscovery/nuclei · error
ds dc info: %w
Error message
ds dc info: %w
What it means
DsDomainControllerInfo asks the DC for information about the domain named by c.Domain; the response supplies fields like NtdsDsaObjectGuid needed later for replication. This error means the call was rejected — most often because the domain string does not match the forest the DC serves, or the caller lacks rights to query DS info.
Source
Thrown at pkg/js/libs/secretsdump/secretsdump.go:141
return nil, fmt.Errorf("open lsass pipe: %w", err)
}
}
rpc := gprpc.NewClient(pipe)
if err := rpc.BindAuth(gpdrs.UUID, gpdrs.MajorVersion, gpdrs.MinorVersion, c.creds); err != nil {
return nil, fmt.Errorf("drsuapi bind: %w", err)
}
defer func() {
_ = rpc.Transport.Close()
}()
bind, err := gpdrs.DsBind(rpc)
if err != nil {
return nil, fmt.Errorf("ds bind: %w", err)
}
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].NameView on GitHub (pinned to 265b3a3dec)
Solutions
- Set the domain to the exact AD domain the DC holds (run nltest /dsgetdc: on the DC to confirm the name)
- Verify with an LDAP query that the account can read rootDSE naming contexts
- Escalate to an account with directory-read rights
Example fix
// before
const c = new sd.Client('dc01.acme.local', 'dc01.acme.local', 'admin', 'P@ss'); // host FQDN used as domain
// after
const c = new sd.Client('dc01.acme.local', 'acme.local', 'admin', 'P@ss'); Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the domain string matches the DC's NC before syncing
nc, err := ldapRootDSE(dc, "defaultNamingContext")
if err == nil && !strings.HasSuffix(nc, ",DC="+strings.ReplaceAll(domain, ".", ",DC=")) {
return fmt.Errorf("domain %q not served by %s", domain, dc)
} Try / catch
secret, err := c.DCSync(target)
if err != nil && strings.Contains(err.Error(), "ds dc info:") {
// domain string mismatch: re-resolve domain from the DC and rebuild the Client
return err
} Prevention
- Source the domain from the DC's rootDSE defaultNamingContext instead of hardcoding
- Distinguish DNS domain from host FQDN in template variables
- Validate domain naming context with one LDAP query before DCSync chains
When it happens
Trigger: new sd.Client('dc01', 'wrongdom', ...) where wrongdom is a typo'd or untrusted domain; domain given as an FQDN where NetBIOS form (or vice versa) is not resolvable by the DC; low-privilege principal denied directory queries.
Common situations: Copy-paste template with the wrong domain value; multi-domain forest where the DC belongs to a child domain; using the host's DNS suffix instead of the AD domain.
Related errors
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/14f6829a12fca20e.
Report an issue: GitHub.