Skip to content

Windows ARM64 CreateFile Hangs on Port Open #3121

@ironsheep

Description

@ironsheep

SerialPort Version

13.0.0

Node Version

v22.21.1

Electron Version

v33.3.1

Platform

PROCESSOR_ARCHITECTURE=ARM64 PROCESSOR_IDENTIFIER=ARMv8 (64-bit) Family 8 Model 0 Revision 0, PROCESSOR_LEVEL=0 PROCESSOR_REVISION=0000

Architecture

arm64

Hardware or chipset of serialport

FTDI

What steps will reproduce the bug?

(See details below.)

What happens?

The SerialPort.open() call hangs indefinitely on Windows ARM64, causing a timeout after 2 seconds. The open() callback never fires (neither success nor error), suggesting the underlying CreateFile Win32 API call is blocking.

Critical Context: Other applications (e.g., PuTTY, terminal emulators) can successfully open and communicate with the same serial port at 2 Mbps on the same Windows ARM64 system, confirming:

  • ✅ FTDI driver works correctly
  • ✅ Serial port hardware is functional
  • ✅ Windows ARM64 can open serial ports
  • Only node-serialport fails to open the port

What should have happened?

The port open callback should fire.

Additional information

NOTE: Running Windows 11, in Parallels Version 26.1.2 (57293) on macOS (Apple Silicon (3.07 GHz)), 8GB RAM, 64-bit operating system, ARM-based processor

Edition Windows 11 Pro
Version 25H2
Installed on ‎8/‎15/‎2025
OS build 26200.7019
Experience Windows Feature Experience Pack 1000.26100.265.0

Verification of Correct Binary

The ARM64 prebuild is being loaded correctly:

[BINDING CHECK] Platform: win32
[BINDING CHECK] Architecture: arm64
[BINDING CHECK] Loaded .node files: [
  'C:\\...\\node_modules\\@serialport\\bindings-cpp\\build\\Release\\bindings.node'
]

Verified the prebuild is actually ARM64:

$ file prebuilds/win32-arm64/@serialport+bindings-cpp.armv8.node
PE32+ executable (DLL) (GUI) Aarch64, for MS Windows, 7 sections

Symptoms

  1. SerialPort.open() is called
  2. Polling shows serialPort.isOpen remains false
  3. The open() callback never fires - no error, no success
  4. After 2 seconds, timeout occurs
  5. Port never opens

Diagnostic Output

[USB OPEN] SerialPort created for COM4
[USB OPEN] Options: {"path":"COM4","baudRate":115200,"dataBits":8,"stopBits":1,"parity":"none","autoOpen":false,"highWaterMark":1048576}
[USB OPEN] Calling serialPort.open() for COM4
[USB OPEN] waitForPortOpen() started - polling isOpen status
[USB OPEN] Poll attempt 0/66: isOpen = false
[USB OPEN] Poll attempt 10/66: isOpen = false
[USB OPEN] Poll attempt 20/66: isOpen = false
[USB OPEN] Poll attempt 30/66: isOpen = false
[USB OPEN] Poll attempt 40/66: isOpen = false
[USB OPEN] Poll attempt 50/66: isOpen = false
[USB OPEN] Poll attempt 60/66: isOpen = false
[USB OPEN] TIMEOUT after 67 attempts - port never opened

Note: No [USB OPEN] open() callback received... message ever appears.

Root Cause Analysis

Based on reviewing the serialport_win.cpp source, the CreateFile call uses:

HANDLE file = CreateFile(
    path,
    GENERIC_READ | GENERIC_WRITE,
    shareMode,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,  // <-- Async I/O
    NULL);

One Hypothesis: The CreateFile call with FILE_FLAG_OVERLAPPED is blocking/hanging on Windows ARM64, never returning control to the callback. But this is only one of possibly many.

Tests Performed

Test 1: DTR/RTS Control

  • Tried both with and without hupcl: false option
  • No difference in behavior

Test 2: Baud Rate

  • Tried 115200 baud (standard rate)
  • Tried 2000000 baud (2 Mbps)
  • No difference in behavior
  • Note: Other apps work at 2 Mbps on the same system

Test 3: Binary Verification

  • Confirmed ARM64 prebuild exists and is Aarch64
  • Confirmed correct binary is being loaded
  • No x64/x86 binary mismatch

Reproduction Steps

  1. Install on a Windows 11 ARM64 system
  2. Connect FTDI USB-serial device (any device that works with other apps)
  3. Run the following code:
import { SerialPort } from 'serialport';

const port = new SerialPort({
  path: 'COM4',  // Adjust to your port
  baudRate: 115200,
  autoOpen: false
});

port.on('open', () => {
  console.log('Port opened!');  // <-- Never called
});

port.on('error', (err) => {
  console.log('Error:', err);   // <-- Never called
});

port.open((err) => {
  if (err) {
    console.log('Callback error:', err);  // <-- Never called
  } else {
    console.log('Callback success!');     // <-- Never called
  }
});

// Check status in a loop
setInterval(() => {
  console.log('isOpen:', port.isOpen);  // Always false
}, 100);
  1. Observe: Callback never fires, isOpen stays false forever

Expected Behavior

Port should open successfully (as it does with other applications on the same system).

Actual Behavior

CreateFile hangs indefinitely, callback never fires.

Additional Context

ARM64 Support Timeline

Possible Causes

  1. Overlapped I/O incompatibility: FILE_FLAG_OVERLAPPED might not work correctly in the ARM64 compiled binary
  2. Compilation issue: The ARM64 binary might have been compiled with incorrect settings
  3. Windows ARM64 CreateFile bug: There might be a Windows ARM64-specific issue with CreateFile on serial ports

Workaround Attempts

None successful. Port opening fails consistently.

Request

Could the serialport team:

  1. Verify the ARM64 Windows prebuild was compiled correctly with proper toolchain
  2. Test on actual Windows ARM64 hardware (not just cross-compilation)
  3. Consider synchronous fallback for Windows ARM64 if FILE_FLAG_OVERLAPPED has issues
  4. Provide build instructions for compiling from source on Windows ARM64 to test locally

System Details

Platform: win32
Architecture: arm64
Node: v22.21.1
Electron: v33.3.1
@serialport/bindings-cpp: 13.0.1
serialport: 13.0.0

Willing to Help

  • Can provide additional diagnostics
  • Can test potential fixes
  • Can help verify patches on Windows ARM64 hardware

For Maintainers

Source code reference (serialport_win.cpp):

  • CreateFile location: OpenBaton::Execute()
  • Flag used: FILE_FLAG_OVERLAPPED
  • Tested devices: FTDI USB-serial (VID 0x0403)

The ARM64 binary loads correctly but CreateFile appears to hang, suggesting a platform-specific issue with the compiled binary rather than a code logic problem.

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