projectdiscovery/nuclei · error

smb session not connected

Error message

smb session not connected

What it means

Session.ListShares calls s.ops(), which returns nil when the Session holds no client: Dial was never completed, failed, Close() already ran, or the Session was built zero-valued / via FromClient(nil). The guard converts that broken state into a clear error instead of a nil-pointer panic inside goimpacket.

Source

Thrown at pkg/js/libs/smbsession/session.go:152

func (s *Session) ops() shareBackend {
	if s == nil {
		return nil
	}
	if s.backend != nil {
		return s.backend
	}
	if s.client == nil {
		return nil
	}
	return s.client
}

// ListShares enumerates share names.
func (s *Session) ListShares() ([]string, error) {
	ops := s.ops()
	if ops == nil {
		return nil, fmt.Errorf("smb session not connected")
	}
	return ops.ListShares()
}

// ListDir lists one directory on share (share-relative path).
func (s *Session) ListDir(share, dir string) ([]Entry, error) {
	ops := s.ops()
	if ops == nil {
		return nil, fmt.Errorf("smb session not connected")
	}
	return listDir(ops, share, dir)
}

// ReadFile reads a file from share, capped at maxBytes (default DefaultMaxReadBytes).
func (s *Session) ReadFile(share, filePath string, maxBytes int64) (string, error) {
	ops := s.ops()
	if ops == nil {
		return "", fmt.Errorf("smb session not connected")

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Always check the error returned by smbsession.Dial before using the session
  2. Do not call methods after Close() — create a new session with Dial
  3. Guard with a connected-check: s != nil && s.Native() != nil
  4. When wrapping an external client with FromClient, verify the client is non-nil first

Example fix

// before
s, _ := smbsession.Dial(ctx, execID, host, 445, creds)
shares, _ := s.ListShares() // smb session not connected

// after
s, err := smbsession.Dial(ctx, execID, host, 445, creds)
if err != nil {
    return err
}
defer s.Close()
shares, err := s.ListShares()
Defensive patterns

Strategy: type-guard

Validate before calling

if s == nil || s.Native() == nil {
    return errors.New("session not connected; dial first")
}
shares, err := s.ListShares()

Type guard

func sessionConnected(s *smbsession.Session) bool {
    return s != nil && s.Native() != nil
}

Try / catch

shares, err := s.ListShares()
if err != nil {
    if strings.Contains(err.Error(), "not connected") {
        // stale/nil session: re-dial once, then give up
        if s, err2 := smbsession.Dial(ctx, execID, host, 445, creds); err2 == nil {
            shares, err = s.ListShares()
        }
    }
}

Prevention

When it happens

Trigger: Ignoring Dial's error and calling methods on the nil session; calling ListShares after s.Close(); constructing smbsession.Session{} directly; smbsession.FromClient(nil) wrapping a nil goimpacket client.

Common situations: Fire-and-forget template code that skips error checks; reusing a session object across scan iterations after teardown; interop code taking a client from dcerpc that may be nil.

Related errors


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