Skip to content

netlify api listSiteDeploys leaks hundreds of thousands of OS handles on Windows, eventually freezing the system #8031

@tobq

Description

@tobq

Summary

netlify api listSiteDeploys on Windows leaks OS handles continuously until the system freezes. Zombie processes accumulate 400,000+ handles each, exhausting the Windows kernel nonpaged pool and causing full system lockups (mouse freezes, no input possible).

Environment

  • OS: Windows 10/11, x64
  • Node.js: v20.19.4 (via nvm4w)
  • netlify-cli: v23.12.3 (globally installed via npm)
  • Shell: Git Bash (MINGW64)
  • Hardware: 64 GB RAM, Ryzen 5 3600, NVMe SSD

Steps to Reproduce

  1. Run netlify api listSiteDeploys --data '{"site_id": "<site_id>", "per_page": 3}'
  2. The command may appear to complete or hang
  3. The node.exe process remains alive as a zombie
  4. Handles accumulate continuously (hundreds per second)
  5. Eventually the system becomes unresponsive

Observed Behavior

Two zombie processes from separate netlify api listSiteDeploys invocations were found on the system:

PID:36908  Handles:407,025  RAM:48MB
CMD: node.exe .../netlify-cli/bin/run.js api listSiteDeploys --data '{"site_id": "...", "per_page": 3}'

PID:293472 Handles:258,708  RAM:68MB
CMD: node.exe .../netlify-cli/bin/run.js api listSiteDeploys --data '{"site_id": "...", "per_page": 5}'

Together they held 665,000+ handles — 73% of all OS handles on the entire system (902,000 total). Normal process handle counts are 200–500.

System-level impact

  • Nonpaged pool: 3,386 MB (normal: ~500 MB). Nonpaged pool is kernel memory that cannot be paged to disk — when exhausted, Windows cannot process mouse/keyboard input or schedule threads.
  • Result: Full system freeze including mouse cursor, requiring hard reboot. This occurred roughly once per day over several weeks.

Expected Behavior

The netlify api command should complete and the node process should exit cleanly, releasing all handles.

Workaround

Replaced all netlify api CLI usage with direct curl calls to https://api.netlify.com/api/v1/sites/<id>/deploys. The REST API works correctly with no handle leaks.

curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.netlify.com/api/v1/sites/$SITE_ID/deploys?per_page=3"

Analysis

The handle leak suggests an unclosed resource (likely event listeners, timers, or file descriptors) in the CLI's process lifecycle — specifically in the api subcommand path. The process doesn't terminate after the API call completes, and some internal loop or watcher continues creating handles indefinitely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions