projectdiscovery/nuclei · error

epmapper bind: %w

Error message

epmapper bind: %w

What it means

TCP to 135 succeeded but the DCE/RPC bind to the EPMAPPER interface (rpc.Bind with the epmapper UUID/version) failed. A protocol-level rejection rather than a connectivity failure: the endpoint-mapper service is broken, or a middlebox (IDS/IPS, RPC filter, TCP proxy) mangles the bind PDU, or (rarely) a version-negotiation mismatch.

Source

Thrown at pkg/js/libs/dcerpc/dcerpc.go:222

// for (const e of eps) { log(e.UUID + ' ' + e.Annotation); }
// ```
func (c *Client) RpcDump(ctx context.Context) ([]Endpoint, error) {
	if !protocolstate.IsHostAllowed(c.nj.ExecutionId(), c.Host) {
		return nil, protocolstate.ErrHostDenied.Msgf(c.Host)
	}
	dialer := protocolstate.GetDialersWithId(c.nj.ExecutionId())
	if dialer == nil {
		return nil, fmt.Errorf("dialers not initialized for execution %s", c.nj.ExecutionId())
	}
	conn, err := dialer.Fastdialer.Dial(ctx, "tcp", net.JoinHostPort(c.Host, strconv.Itoa(135)))
	if err != nil {
		return nil, fmt.Errorf("dial epmapper: %w", err)
	}
	defer func() { _ = conn.Close() }()

	rpc := gprpc.NewClientTCP(gprpc.NewTCPTransport(conn))
	if err := rpc.Bind(gpepm.UUID, gpepm.MajorVersion, gpepm.MinorVersion); err != nil {
		return nil, fmt.Errorf("epmapper bind: %w", err)
	}
	epm := gpepm.NewEpmClient(rpc)
	return epm.Lookup()
}

// SamrEnumerateUsers connects to SAMR and returns every domain user record
// (impacket: samrdump.py).
//
// @example
// ```javascript
// const c = new dcerpc.Client('dc01', 'acme.local', 'admin', 'P@ss');
// const users = c.SamrEnumerateUsers();
// for (const u of users) { log(u.Name + ' ' + u.RID); }
// ```
func (c *Client) SamrEnumerateUsers() ([]DomainUser, error) {
	rpc, err := c.rpcOverNamedPipe("samr", gpsamr.UUID, gpsamr.MajorVersion, gpsamr.MinorVersion)
	if err != nil {
		return nil, err

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Cross-check with impacket's rpcdump.py — if it also fails, the problem is host-side or path-side, not nuclei.
  2. Retry once: some middleboxes drop the first PDU of a connection.
  3. Inspect the path for IPS/proxies that intercept 135.
  4. Fall back to named-pipe enumeration methods over 445 which avoid the endpoint mapper.

Example fix

// before
const eps = c.RpcDump(); // epmapper bind: ...

// after (single retry, then fall back)
let eps = null;
for (let i = 0; i < 2 && eps === null; i++) {
  try { eps = c.RpcDump(); } catch (e) { log('epmapper bind attempt ' + i + ' failed: ' + e); }
}
if (eps === null) eps = []; // continue with pipe-based methods instead
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const eps = c.RpcDump();
} catch (e) {
  const msg = String(e);
  if (msg.includes('epmapper bind')) {
    // port 135 answers but RPC bind is rejected: middlebox or broken service
    log('epmapper bind rejected: ' + msg);
  } else throw e;
}

Prevention

When it happens

Trigger: RpcDump() where something answers on 135 but never returns a valid bind ack: crashed RPC service after patching, transparent proxies/IPS on the path, or a honeypot accepting any TCP connection.

Common situations: IPS signatures tripping on DCE/RPC binds; partially broken hosts; deceptive endpoints answering all ports.

Related errors


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