projectdiscovery/nuclei · error

open pipe %q: %w

Error message

open pipe %q: %w

What it means

Thrown by the shared rpcOverNamedPipe helper in nuclei's dcerpc JS library after the SMB session on 445 is already established: c.smb.OpenPipe(pipe) failed to open the requested Windows named pipe (samr, lsarpc, svcctl, ctx_winstation), with the pipe name embedded in the message. It means the host speaks SMB but does not expose that pipe — the backing Windows service is stopped/absent, or the session lacks rights to open it (STATUS_OBJECT_NAME_NOT_FOUND / STATUS_ACCESS_DENIED).

Source

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

}

// Close releases the underlying SMB session.
func (c *Client) Close() {
	if c.smb != nil {
		c.smb.Close()
	}
	c.started = false
}

// rpcOverNamedPipe binds the supplied interface UUID over a named pipe and
// returns an authenticated *dcerpc.Client.
func (c *Client) rpcOverNamedPipe(pipe string, uuid [16]byte, major, minor uint16) (*gprpc.Client, error) {
	if err := c.connect(); err != nil {
		return nil, err
	}
	pf, err := c.smb.OpenPipe(pipe)
	if err != nil {
		return nil, fmt.Errorf("open pipe %q: %w", pipe, err)
	}
	rpc := gprpc.NewClient(pf)
	if err := rpc.BindAuth(uuid, major, minor, c.creds); err != nil {
		_ = pf.Close()
		return nil, fmt.Errorf("dcerpc bind: %w", err)
	}
	return rpc, nil
}

// RpcDump enumerates every RPC endpoint registered with the EPMAPPER over
// ncacn_ip_tcp/135 (impacket: rpcdump.py).
//
// @example
// ```javascript
// const dcerpc = require('nuclei/dcerpc');
// const c = new dcerpc.Client('dc01', 'acme.local', 'admin', 'P@ss');
// const eps = c.RpcDump();
// for (const e of eps) { log(e.UUID + ' ' + e.Annotation); }

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Enumerate what the target actually exposes: call c.RpcDump() (EPMAPPER on tcp/135) or list pipes with the nuclei smb library and confirm the pipe exists.
  2. Run/enable the backing Windows service on the target (Server service for svcctl, Task Scheduler for atsvc) or pick a host that exposes the pipe.
  3. Re-run with credentials that have rights to the pipe: valid domain user/password in new dcerpc.Client(...), or SetHash()/SetKerberos() for pass-the-hash/Kerberos.
  4. If the pipe is deliberately removed by hardening, treat the endpoint as unavailable and pivot to a different interface (e.g. lsarpc instead of samr).

Example fix

// before
const c = new dcerpc.Client('dc01', 'ACME', 'user', 'pass');
const users = c.SamrEnumerateUsers(); // throws: open pipe "samr": ...

// after
const c = new dcerpc.Client('dc01', 'ACME', 'user', 'pass');
try {
  const users = c.SamrEnumerateUsers();
} catch (e) {
  // pipe-level failure: see what the host actually serves
  const eps = c.RpcDump().filter(ep => String(ep.Protocol||'').includes('ncacn_np'));
  log('samr pipe unavailable; named-pipe endpoints: ' + to_json(eps));
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const users = c.SamrEnumerateUsers();
} catch (e) {
  const msg = String((e && e.message) || e);
  if (msg.includes('open pipe')) {
    // pipe-level: host does not serve this RPC endpoint or denied the open
    log('pipe unavailable: ' + msg);
  } else {
    throw e; // different failure class
  }
}

Prevention

When it happens

Trigger: Any method routed through rpcOverNamedPipe: SamrEnumerateUsers(), SamrAddComputer() (pipe 'samr'), LsaLookupSids() ('lsarpc'), EnumServices()/EnumSessions() ('svcctl'/'srvsvc'), EnumProcesses() ('ctx_winstation'). Fires when OpenPipe errors, e.g. Task Scheduler stopped so the pipe is missing, or 'samr' removed by SAM-RPC hardening on a patched DC.

Common situations: Non-admin or null-session credentials denied the pipe open; hardening that removes samr/lsarpc from domain controllers; EDR products that block named-pipe opens; Samba appliances implementing only a subset of pipes.

Related errors


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