rust-lang/rust-analyzer · error
tried to set QoS of thread which has opted out of QoS (os er
Error message
tried to set QoS of thread which has opted out of QoS (os error {errno}) What it means
On macOS, rust-analyzer manages thread priority exclusively through QoS (Quality of Service) APIs (`pthread_set_qos_class_self_np`). If setting the QoS class returns ENOTSUP/ENOTSCHED (errno stored), the thread has previously opted out of the QoS system — e.g. via `pthread_setschedparam`-style scheduling calls incompatible with QoS — and can no longer use QoS APIs. The code deliberately panics instead of returning an error to uphold the invariant that only QoS APIs are used for thread intent.
Source
Thrown at crates/stdx/src/thread/intent.rs:198
};
let code = unsafe { libc::pthread_set_qos_class_self_np(c, 0) };
if code == 0 {
return;
}
let errno = unsafe { *libc::__error() };
match errno {
libc::EPERM => {
// This thread has been excluded from the QoS system
// due to a previous call to a function such as `pthread_setschedparam`
// which is incompatible with QoS.
//
// Panic instead of returning an error
// to maintain the invariant that we only use QoS APIs.
panic!("tried to set QoS of thread which has opted out of QoS (os error {errno})")
}
libc::EINVAL => {
// This is returned if we pass something other than a qos_class_t
// to `pthread_set_qos_class_self_np`.
//
// This is impossible, so again panic.
unreachable!(
"invalid qos_class_t value was passed to pthread_set_qos_class_self_np"
)
}
_ => {
// `pthread_set_qos_class_self_np`'s documentation
// does not mention any other errors.
unreachable!("`pthread_set_qos_class_self_np` returned unexpected error {errno}")
}
}View on GitHub (pinned to e8f7e90aa3)
Solutions
- Stop using non-QoS scheduling APIs (`pthread_setschedparam` etc.) on threads managed by stdx::thread; rely on ThreadIntent/QoS only
- Spawn a fresh thread that has never had its policy modified and use QoS intent APIs from the start
- If you must use manual scheduling, do not attempt QoS calls afterward on that thread
Example fix
// before pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); stdx::thread::set_current_thread_qos_class(...).unwrap(); // panics // after // drop the manual scheduling call entirely stdx::thread::set_current_thread_qos_class(...).unwrap();
Defensive patterns
Strategy: validation
Validate before calling
// Before managing intent, confirm the thread hasn't been policy-modified:
let class = libc::qos_class_self(); // probing is safe
if class == libc::QOS_CLASS_UNSPECIFIED {
eprintln!("thread opted out of QoS; skip set_current_thread_qos_class");
} else {
stdx::thread::set_current_thread_qos_class(intent)?;
} Try / catch
// Guard the process-level invariant during embedding:
let result = std::panic::catch_unwind(||
stdx::thread::set_current_thread_qos_class(ThreadIntent::Worker)
); Prevention
- Never call pthread_setschedparam/thread_policy_set on stdx::thread-managed threads
- Use ThreadIntent/QoS as the only priority mechanism on macOS
- If manual scheduling is required, run it on separate threads from intent-managed ones
When it happens
Trigger: Calling `set_current_thread_qos_class` on a thread whose scheduling was previously modified by a non-QoS API such as `pthread_setschedparam`, `thread_policy_set`, or manual scheduling; mixing `stdx::thread` intent APIs with platform-specific priority tweaks in the same thread.
Common situations: Developers integrating custom thread priority/scheduling code (real-time audio-style policies) alongside rust-analyzer's thread pool on macOS; embedding rust-analyzer in an app that adjusts thread policies on its worker threads.
Related errors
- tried to get QoS of thread which has opted out of QoS
- We explicitly do not provide canonicalization API, as that i
- bad kind {other}
- bad spacing {other}
- bad tag: {other}
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/226964a51424f888.
Report an issue: GitHub.