I am sure some of you have come across NDI Local Network Permissions Issue in Tahoe 26.4.1. I encountered this on a new MacStudio M4 Max (not on a laptop M1 Max). In this case I was using VDMX as a syphon input to QLab in in my installation, but I am sure this approach works for stand alone use too.
I hope that there is a simpler way, but this is where I am:
On macOS Tahoe 26.4.1, NDI video streams received by VDMX6 and NDI Router become blocked after a system reboot, even though the Local Network permission for those apps appears to be granted in System Settings. VISCA camera control through the same machine is unaffected, which suggests the problem is specific to multicast and Bonjour-based discovery traffic governed by the Local Network privacy subsystem, rather than a general network failure. The streams can be restored by manually toggling any NDI-using app’s Local Network permission off and on in System Settings > Privacy & Security > Local Network. This side-effect appears to reset the privacy subsystem’s state for all registered NDI clients at once, rather than only the toggled app.
No programmatic alternative was found. Restarting mDNSResponder had no effect. tccutil does not manage Local Network state, because Apple stores it in /Library/Preferences/com.apple.networkextension.*.plist rather than the TCC database. Restarting com.apple.nesessionmanager via launchctl kickstart is blocked by System Integrity Protection. Cycling the Ethernet interface via networksetup did not unblock the streams. Quitting and relaunching VDMX or NDI Router did not restore them either. The System Settings permission toggle was the only action that worked reliably.
An AppleScript was developed to automate that toggle, suitable for triggering from a QLab Script cue as the first step in a workspace that opens automatically at login. The script opens System Settings to Privacy & Security via its URL scheme, navigates into the Local Network pane by clicking the category button through its accessibility tree path, polls for the VDMX6 checkbox to appear in the accessibility tree (which takes a variable amount of time after the pane loads), and then presses the checkbox twice to toggle the permission off and back on. System Settings is then quit. The category click uses an accessibility path obtained via Accessibility Inspector rather than screen coordinates, because coordinate-based clicks proved fragile across display resolutions and because Tahoe exposes the category buttons without accessible names. The direct URL anchor Privacy_LocalNetwork was tested and found to open the pane visually but produce an accessibility tree in which the VDMX6 checkbox cannot be located, so navigation via the URL anchor is not viable.
The script runs as QLab’s first cue at workspace open, followed by a delay of several seconds before VDMX6 and NDI Router are launched from later cues. QLab must have Accessibility permission granted. The approach depends on System Settings’ accessibility tree structure, which Apple may change between macOS point releases; the mitigation is to disable automatic macOS updates on the installation machine and apply them manually during maintenance windows where the script can be retested.
My script:
– Toggle VDMX6’s Local Network permission off and back on
-- macOS Tahoe 26.4.1, installation Mac Studio
property appToToggle : “VDMX6”
property settleDelay : 0.6
on run
open location "x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension"
delay 1.5
tell application "System Events"
tell process "System Settings"
set frontmost to true
delay 0.5
-- Click Local Network via its accessibility path
click button 9 of group 4 of scroll area 1 of group 1 of group 3 of splitter group 1 of group 1 of window "Privacy & Security"
delay 1.0
-- Poll for VDMX6's checkbox up to 10 seconds
set theBox to missing value
repeat 20 times
set theBox to my findCheckboxNamed(window 1, appToToggle)
if theBox is not missing value then exit repeat
delay 0.5
end repeat
if theBox is missing value then error "Could not find checkbox for " & appToToggle & "."
perform action "AXPress" of theBox
delay settleDelay
perform action "AXPress" of theBox
delay 0.3
end tell
end tell
tell application "System Settings" to quit
end run
on findCheckboxNamed(container, targetName)
set found to {missing value}
my searchCheckbox(container, targetName, found)
return item 1 of found
end findCheckboxNamed
on searchCheckbox(el, targetName, foundRef)
if item 1 of foundRef is not missing value then return
tell application "System Events"
try
if (role of el) is "AXCheckBox" then
try
if (name of el) is targetName then
set item 1 of foundRef to contents of el
return
end if
end try
end if
end try
try
repeat with child in (UI elements of el)
my searchCheckbox(child, targetName, foundRef)
if item 1 of foundRef is not missing value then return
end repeat
end try
end tell
end searchCheckbox