projectdiscovery/nuclei · error

ds dc info

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.

Solutions

  1. Set the domain to the exact AD domain the DC holds (run nltest /dsgetdc: on the DC to confirm the name)
  2. Verify with an LDAP query that the account can read rootDSE naming contexts
  3. 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

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.

Appendix: 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].Name

View on GitHub (pinned to 265b3a3dec)