Skip to content

Can't trigger Lame Duck Mode on Windows (non-service mode) #7911

@tltsaia

Description

@tltsaia

Proposed change

Hey team! 👋

I ran into something that's been bugging me on Windows. When I'm running nats-server.exe directly (not as a Windows Service), there's no way to trigger Lame Duck Mode. The only option is Ctrl+C, which just kills everything immediately.

What's happening now

On Windows:

  • Running as a Windows Service → looks like nats-server --signal ldm should work (based on the code in service_windows.go)
  • Running directly as a regular process → No way to trigger LDM, stuck with hard shutdown

On Linux/Unix (from looking at the code):

  • Looks like it supports kill -SIGUSR2 <pid> or nats-server --signal ldm
  • Plus other signals like SIGUSR1 for log reopen, SIGHUP for reload, etc.

Why this is a pain

Development: When I'm testing locally on Windows, I just run nats-server.exe. Can't test LDM behavior at all without spinning up an actual Windows Service, which is annoying.

Cross-platform consistency: It'd be nice to have the same command-line experience across platforms, especially for deployment automation.

Production: Not every scenario needs or wants Windows Service mode, but we still need graceful shutdown.

What would be awesome

If Windows non-service mode could support LDM just like Linux does. Something where I can say "hey, go into lame duck mode" without needing to install it as a service.

Side note: nginx figured this out

Just FYI, nginx had the exact same problem (Windows doesn't have Unix signals), and they solved it pretty nicely:

nginx.exe -s stop      # fast shutdown
nginx.exe -s quit      # graceful shutdown
nginx.exe -s reload    # reload config
nginx.exe -s reopen    # reopen logs

Works the same way on Windows and Linux. They use Windows Event objects under the hood for IPC. Not saying you should do it exactly the same way, but it shows it's definitely doable and has been working well for them.

Check out https://nginx.org/en/docs/windows.html if you're curious.

Environment

  • NATS Server: v2.12.5-RC.2
  • OS: Windows 10/11 / Windows Server
  • Mode: Direct exe or Docker container

Code pointers

If it helps:

  • server/signal_windows.go - currently only handles basic interrupts
  • server/signal.go - Unix/Linux version with full signal support
  • server/service_windows.go - Service mode does support LDM via ldmCmd

Would love to have consistent behavior across platforms! Thanks for all the great work on NATS ❤️

Related to: graceful shutdown, cluster rolling updates, JetStream Raft leadership transfer, avoiding client reconnection storms

Use case

Quick repro

# Start nats-server normally
.\nats-server.exe

# Try to trigger LDM
.\nats-server.exe --signal ldm=12345

# Gets: "could not access service" error

Contribution

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalEnhancement idea or proposal

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions