|
libfreenect2 0.4
Open source driver for the Kinect for Windows v2 (K4W2) sensor
|
A diagnostic flow, ordered so that each stage rules out a class of problem before the next. Work top to bottom; most reports resolve in the first two sections.
For questions about what the data means rather than why it is missing, see the Frequently asked questions. For USB bandwidth theory and transfer tuning, see USB bandwidth and transfer tuning.
Signatures marked (Linux) below are drawn from the upstream issue corpus and the upstream troubleshooting wiki, which was last edited in 2017. They were not reproducible on this project's macOS validation host. Treat them as leads, not guarantees.
Protonect prints no Initialization and Device Control connected!, or Freenect2::enumerateDevices() returns 0.
The Kinect v2 requires its dedicated AC adapter — the USB connection alone will not power it. A lit white LED on the sensor means it is powered. Replug both the adapter and the USB cable, and give the device a few seconds to enumerate.
USB 2 is not supported at all, and the link must actually negotiate SuperSpeed:
Anything below 5000M means a bad cable, a USB 2 port, or a marginal link. Connect directly to a port on the machine — not through a hub, and preferably not a front-panel header.
Identify the controller before reporting a problem:
Intel and NEC controllers are widely reported to work. ASMedia controllers are widely reported not to work; if yours is ASMedia, try a different controller before spending time elsewhere.
Without the udev rule the device nodes are root-only. Install it:
Then unplug and replug the sensor. The rule sets MODE="0666" on Microsoft vendor 045e, products 02c4, 02d8, and 02d9.
To confirm it applied, check the node's mode rather than re-running the viewer as root:
Do not diagnose by running Protonect under sudo. It can succeed or fail for reasons unrelated to USB permissions — under a desktop session the GL/GLFW context may not open for the root user at all — so the result is ambiguous either way, and it can leave root-owned files behind. Checking the node mode answers the same question unambiguously.
At open, libfreenect2 now rejects a known USB 2 link before resetting the sensor and reports when a kernel driver owns either video interface. It never detaches that driver automatically. A LIBUSB_ERROR_BUSY claim failure can also mean that another Kinect, OpenNI, or Kinect SDK process already has the interface open. Stop the competing process or service, confirm the link is still 5000M with lsusb -t, and retry. On Linux, sudo fuser -v /dev/bus/usb/BBB/DDD can identify processes holding the device node.
USB 3.0 isochronous transfer rarely survives a VM's USB passthrough. Run on bare metal before investigating anything else.
libfreenect2 needs UsbDk or libusbK bound to the composite parent device; the stock Kinect SDK driver will not work. See Installing on Windows.
LIBUSB_ERROR_NOTSUPPORTED specifically means the libusb you are linking was not built with its libusbK backend enabled. Rebuild it, checking the build log for the errors that silently disabled the backend, or use a prebuilt binary.
If streaming starts and then degrades, also disable USB selective suspend in the Windows power plan — it is the Windows equivalent of the autosuspend problem described in section 2.
If the sensor does not appear, open System Information, go to the USB section, and confirm Xbox NUI Sensor is listed under a USB 3.0 SuperSpeed Bus and not a High-Speed Bus. If it is on the wrong bus, unplug the sensor's power while leaving USB connected, then reconnect power and re-check.
Thunderbolt-to-USB 3.0 adaptors are a recurring source of instability for isochronous transfers, as are USB 3 hubs. Connect directly to a built-in port before investigating anything else.
The device enumerates and opens, then waitForNewFrame() times out or frames arrive with gaps.
Before blaming USB, remove the GPU from the picture:
If CPU is stable and a GPU pipeline is not, the fault is in the depth backend — skip to section 3, A backend fails. If CPU also stalls, the problem is USB or the device, and belongs in this section.
Narrow further by disabling one stream:
If either stream alone is stable but both together are not, the controller does not have the bandwidth for the pair. That is a topology problem, not a tuning problem.
A single Kinect v2 consumes most of a USB 3.0 controller. Move other high-bandwidth devices to a different controller, and never share a controller between two sensors. See USB bandwidth and transfer tuning for the full budget discussion.
| Message | Severity | Meaning |
|---|---|---|
| xhci_hcd … ERROR Transfer event TRB DMA ptr not part of current TD | Depends — see below | Common xHCI chatter during isochronous streaming; not by itself a fault |
| xhci_hcd … WARN Event TRB for slot … with no TDs queued | Usually harmless | Same class of noise. Emitted by bulk transfers that request a larger buffer than they receive, which is exactly what the calibration and P0 table reads do. |
| xhci xhci_drop_endpoint called with disabled ep | Harmless | Emitted during configuration. The kernel stopped printing it in 4.0. |
| Not enough bandwidth for new Initialization and Device Control state | Fatal | The controller cannot admit the isochronous endpoint. Move the sensor to its own controller. |
| Initialization and Device Control descriptor read/64, error -110 | Fatal | Timeout. Cable, power, or port. |
| usb … reset SuperSpeed USB Initialization and Device Control number … using xhci_hcd | Investigate | A single reset at start can be normal; repeated resets mean an unstable link |
| Allocation failure / -ENOMEM on submit | Fatal | The usbfs memory limit is too low. See below. |
| page allocation failure: order:7 in proc_do_submiturb | Fatal | Memory fragmentation, not exhaustion — the kernel could not find a large enough contiguous block for the transfer buffer. See below. |
Most of these appear on healthy systems and are not worth reporting on their own, whereas bandwidth and -110 errors are conclusive.
The TRB error is the one that needs reading in context. On its own it is noise. When it escalates into this sequence it is not:
That is the controller failing, and it usually surfaces to the application as LIBUSB_ERROR_NO_DEVICE. It is characteristic of ASMedia controllers, which appear to be missing the kernel's XHCI_SPURIOUS_SUCCESS quirk. You can test that hypothesis by booting with xhci_hcd.quirks=0x10, but the reliable fix is a different controller — see the controller guidance in section 1.
page allocation failure: order:7 means the kernel could not find 128 contiguous pages, even though total free memory may be ample. Raising the kernel's free-memory reserve gives the allocator room to keep large blocks available:
Keep the value under about 5% of total RAM. This is a system-wide change that permanently withholds memory from everything else; treat it as a last resort, and see the caveats in USB bandwidth and transfer tuning.
The kernel caps memory pinned for USB transfers, and the default is often too low:
This does not survive a reboot; see USB bandwidth and transfer tuning to persist it. The limit does not exist on macOS or Windows.
Linux may suspend an idle sensor mid-session. Scope the fix to the Kinect rather than disabling autosuspend for every USB device on the machine, and note that it reverses with auto or a replug. Procedure in USB bandwidth and transfer tuning.
A last resort, after topology and the usbfs limit. The four LIBFREENECT2_*_TRANSFERS / *_PACKETS variables and their platform defaults are documented in USB bandwidth and transfer tuning and Runtime configuration reference. No pool size compensates for two sensors on one controller.
Device and arrival clocks differ, and color and depth are not hardware synchronized. Check Frame timing and software pairing for what the timestamps mean and what pairing guarantees actually exist.
The requested pipeline is not used, or depth output is wrong on one backend and right on another.
libfreenect2 logs a warning and falls through the chain metal → opengl → cuda → opencl → cpu, probing each for a usable runtime device:
The positional Protonect spellings are strict. For example, Protonect cl exits before USB enumeration when OpenCL was not compiled or exposes no usable device; it does not silently fall back. Use LIBFREENECT2_PIPELINE=opencl when fallback to another backend is acceptable.
| Backend | Check |
|---|---|
| Metal | macOS only. The log names the GPU it selected, e.g. MetalDepthPacketProcessor: using Initialization and Device Control Apple M4 Pro. |
| OpenGL | Needs OpenGL 3.1; OpenGL ES is unsupported. Verify with glxinfo \| grep OpenGL: the core-profile or plain version string must exceed 3.1, and the renderer must not be llvmpipe (software rasterization). An insufficient version surfaces as GLFW error 65543 The requested client API version is unavailable. Deprecated by Apple — prefer metal there. |
| OpenCL | Verify the ICD stack with clinfo before suspecting libfreenect2. An unusable explicit Protonect cl selection is fatal; an environment-selected OpenCL preference is skipped. |
| CUDA | Hosted CI compiles the CUDA pipelines but does not validate them at runtime. Compare CUDA against CPU output on your own hardware. |
| VAAPI | Intel, Ivy Bridge or newer, Linux only. Select an explicit node with LIBFREENECT2_VAAPI_DEVICE=/dev/dri/renderD128 if autodetection picks the wrong one. |
the provided PTX was compiled with an unsupported toolchain means the NVIDIA driver cannot JIT the PTX produced by the selected CUDA toolkit. Confirm the GPU and installed driver with nvidia-smi, then either update the driver or rebuild with a toolkit supported by that driver. Set CMAKE_CUDA_ARCHITECTURES to the compute capability of the target GPU. An explicit Protonect cuda or Protonect cudakde selection exits before USB enumeration when CUDA initialization already reports the pipeline unhealthy; select cpu to confirm the sensor and USB path independently.
On Intel Macs with NVIDIA graphics, the opengl pipeline can abort inside gldCreateDevice() in GeForceGLDriver. Confirm with a stack trace from lldb. This is a defect in NVIDIA's macOS OpenGL driver with no fix available; use the opencl pipeline instead, or force the process onto the integrated Intel GPU. Apple Silicon is unaffected — use metal there.
The VideoToolbox decoder crashes on M1 and later. ENABLE_VIDEOTOOLBOX already defaults to OFF on Apple Silicon so TurboJPEG is used instead; if you forced it ON, turn it back off.
or many missing libusb/GLFW symbols. CMake detects this at configure time and stops with instructions. Run arch — it must print arm64 on Apple Silicon. A shell, IDE, or CMake launched under Rosetta produces x86_64 builds that cannot link Homebrew's arm64 libraries in /opt/homebrew. Full detail in Installing on macOS.
See Recording, replay, and multiple Kinects for the software side, and USB bandwidth and transfer tuning for why the one-per-controller rule exists.
Depth accuracy problems are usually calibration, not a driver fault.
Every clean shutdown on macOS currently logs:
This occurs during teardown, after streaming has finished, because the device has already dropped off the bus by the time the interface is released. It is reproducible on every run and does not indicate lost or corrupted frames — captures complete normally. It is safe to ignore unless it appears before stopped.
Set the default level with LIBFREENECT2_LOGGER_LEVEL (debug, info, warning, error, none), or install a custom libfreenect2::Logger. See Runtime configuration reference and the Frequently asked questions.
Open an issue at https://github.com/hbmartin/libfreenect2-metal/issues.
A complete report includes:
| Item | Command |
|---|---|
| Exact command run | — |
| Commit | git log -1 --oneline |
| OS and kernel | uname -a / sw_vers |
| USB topology and link speed | lsusb -t / system_profiler SPUSBDataType |
| Host controller ID | lspci -nn \| grep -i usb |
| Kernel messages | dmesg from around the failure |
| Pipeline in use | the LIBFREENECT2_PIPELINE value, or the pipeline the device reported |
| GPU and driver version | — |
| libusb diagnostics | LIBUSB_DEBUG=3 output |
Note any system-wide changes you have already made — kernel boot parameters, vm.min_free_kbytes, autosuspend settings — since they change the baseline your results are measured against.