Skip to content

[coreaudio] Device UIDs with non-ASCII characters are corrupted — CFStringGetSystemEncoding() should be kCFStringEncodingUTF8 #1017

Description

@zinc75

Describe the bug

When a CoreAudio device UID contains non-ASCII UTF-8 characters, Jack2
stores it internally with a corrupted encoding. Passing the correct UTF-8
UID via -C, -P or -d causes Jack to silently fall back to the default
device instead of using the requested one.

Environment

  • JACK Version: 1.9.22 (installed via official pkg)
  • Operating System: macOS 15.x Sequoia and macOS 26.x Tahoe (tested on
    multiple machines, Intel and Apple Silicon)
  • Installation: Official pkg

Steps To Reproduce

With a RØDE AI-Micro USB audio interface connected (or any device whose name
contains non-ASCII characters):

# 1. List devices — note the corrupted bytes in the UID (shown as '?' in most terminals)
jackd -d coreaudio -l

# 2. Launch Jack with the correct UTF-8 CoreAudio UID → silently falls back
#    to the default device instead of using the RØDE
jackd -d coreaudio -r 48000 -p 1024 \
  -C "AppleUSBAudioEngine:RØDE:RØDE AI-Micro:843EC100:2,3"

# 3. Extract the raw (corrupted) internal UID from jackd -l output
#    (sed chokes on the non-UTF-8 bytes; perl handles arbitrary bytes)
JACK_UID=$(jackd -d coreaudio -l 2>&1 \
  | perl -ne "/'([^']+)'\s+\(to be used/ and print \$1" \
  | grep -a "AI-Micro")

# 4. Pass the raw corrupted UID back → Jack recognises the device correctly
jackd -d coreaudio -r 48000 -p 1024 -C "$JACK_UID"

Expected vs. actual behavior

Expected: passing the CoreAudio UTF-8 UID (as returned by
kAudioDevicePropertyDeviceUID) selects the correct device.

Actual: Jack silently falls back to the default device. jackd -l
reveals that the UID is stored internally with corrupted bytes — the UTF-8
sequence for Ø (0xC3 0x98) is misinterpreted as two separate MacRoman
characters, producing a byte sequence that no longer matches what the caller
passes in.

Step 4 above confirms this is a round-trip encoding mismatch: the raw bytes
extracted from jackd -l (the corrupted form) are accepted by Jack, while
the correct UTF-8 form is rejected.

The bug is therefore in how Jack reads and stores device UIDs internally,
not in how CoreAudio exposes them.

Workaround

Until this is fixed in Jack itself, it is possible to work around it by
running jackd -d coreaudio -l, extracting the raw (corrupted) internal UID
via byte-level parsing with perl, and passing that form back to jackd
(step 4 above).

The bug is therefore in how Jack reads and stores device UIDs internally,
not in how CoreAudio exposes them.

Until this is fixed in Jack itself, it is possible to work around it by
running jackd -d coreaudio -l, extracting the raw (corrupted) internal UID
via byte-level parsing with perl, and passing that form back to jackd
(step 4 above).

I'm currently implementing this workaround in JackMate,
a macOS app for managing the Jack server: at startup and on device change,
JackMate will run jackd -d coreaudio -l, parses the raw output, and substitutes
the Jack-internal UID for the CoreAudio one when building the command line, but I really think this should be fixed upstream in Jack2 as RØDE is far from being a confidential audio devices vendor (and that could also impact other devices with non-ASCII characters).

I am willing to investigate the root cause in the Jack2 source and submit
a PR with a fix if that would be welcome.

Note

This specific issue may be macOS-only (CoreAudio device enumeration). Other
platform drivers may have similar encoding assumptions worth reviewing, but
that is out of scope for this report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions