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
- Always check the error returned by smbsession.Dial before using the session
- Do not call methods after Close() — create a new session with Dial
- Guard with a connected-check: s != nil && s.Native() != nil
- 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
- Always check Dial's error and abort on failure
- Close a session exactly once and never use it afterwards
- Scope the Session variable to the code region that owns its lifetime
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
- no templates provided for scan
- no input provider found
- no templates provided for scan
- template threads must be at least 1
- host concurrency must be at least 1
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/6eed981b67ec42ce.
Report an issue: GitHub.