python/cpython · warning
detach_thread: failed detaching thread\n
Error message
detach_thread: failed detaching thread\n
What it means
Diagnostic printed to stderr by the _thread module's ThreadHandle implementation when the underlying OS call to detach a joinable thread fails (non-zero return) during interpreter/thread teardown. It indicates the OS refused to detach — typically because the thread is not in a detachable state — but execution continues; it is a warning-level trace, not a raised exception.
Source
Thrown at Modules/_threadmodule.c:261
return self;
}
static void
ThreadHandle_incref(ThreadHandle *self)
{
_Py_atomic_add_ssize(&self->refcount, 1);
}
static int
detach_thread(ThreadHandle *self)
{
if (!self->has_os_handle) {
return 0;
}
// This is typically short so no need to release the GIL
if (PyThread_detach_thread(self->os_handle)) {
fprintf(stderr, "detach_thread: failed detaching thread\n");
return -1;
}
return 0;
}
// NB: This may be called after the PyThreadState in `thread_run` has been
// deleted; it cannot call anything that relies on a valid PyThreadState
// existing.
static void
ThreadHandle_decref(ThreadHandle *self)
{
if (_Py_atomic_add_ssize(&self->refcount, -1) > 1) {
return;
}
// Remove ourself from the global list of handles
HEAD_LOCK(&_PyRuntime);
if (self->node.next != NULL) {View on GitHub (pinned to bc6749cc3b)
Solutions
- Ensure threads are either joined (thread.join()) or fully detached consistently before interpreter shutdown
- Avoid mixing raw pthread_create/detach from extensions with Python _thread handles for the same thread
- Upgrade CPython — thread teardown handling in this path has seen fixes across releases
- If it only appears at exit with daemon threads, convert critical threads to non-daemon and join them
Defensive patterns
Strategy: fallback
Prevention
- Join or explicitly detach every thread before interpreter shutdown
- Do not manage the same OS thread from both raw pthreads and _thread handles
- Keep daemon threads only for truly disposable work; join critical ones
- Track the CPython version — teardown races in this area have been patched over time
When it happens
Trigger: ThreadHandle cleanup at interpreter shutdown or Thread object deallocation calling PyThread_detach_thread() on pthreads whose state is no longer joinable-detachable (already exited and reaped, or detached elsewhere); races between thread exit and handle finalization.
Common situations: Heavy multithreaded programs embedding CPython exiting while daemon threads are being torn down; C extensions creating raw pthreads that interact with Python thread handles; observed on platforms with stricter pthread lifecycle enforcement. No Python-level exception is raised.
Related errors
- Initialization arguments are not supported
- %r object attribute '__dict__' is read-only
- locale changed during initialization
- timezone changed during initialization
- Day of month directive '%d' may not be used without a year d
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/87f07f318f2a3d6f.
Report an issue: GitHub.