TypeError can't pickle _thread.RLock objects
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
TypeError: can't pickle _thread.RLock objects appears when Python tries to serialize an object graph that contains a reentrant lock. The lock itself is not meaningful outside the current process and thread state, so modules such as multiprocessing and concurrent.futures.ProcessPoolExecutor cannot pickle it and send it elsewhere.
Why Pickling Fails
Pickling works for data that can be serialized into bytes and reconstructed later. A _thread.RLock is a live synchronization primitive tied to runtime state, not just data.
That is why code like this fails:
The Worker instance contains self.lock, so sending it to another process requires pickling that lock. Python refuses because the lock cannot be reconstructed meaningfully.
Where This Usually Happens
This error often appears indirectly. You may not be pickling a lock on purpose. Instead, you are pickling an object that contains one.
Common examples include:
- class instances with
threading.Lockorthreading.RLockfields - objects holding loggers, queues, or clients that embed locks internally
- bound methods where
selfcontains an unpicklable lock
That last case surprises people often. Sending obj.method to a process pool also sends obj.
The Best Fix: Do Not Send the Lock
The cleanest fix is to keep synchronization primitives local to the process that owns them and pass only serializable data to worker processes.
If the worker really needs a lock, create it inside that process instead of serializing one from the parent.
Rebuilding the Lock with __getstate__
If you need the class to remain picklable, exclude the lock from serialized state and recreate it on unpickle.
This works when the lock protects local in-process state and does not need to preserve ownership or lock count across serialization.
Threads and Processes Are Different Problems
Sometimes the presence of an RLock is a clue that you actually want threads, not processes. Threads share memory inside one process, so you do not need to pickle the object graph just to execute code concurrently.
If the workload is I/O-bound and already structured around shared objects with locks, a thread pool may be more natural than a process pool.
Common Pitfalls
The biggest pitfall is looking only at your own code and missing that a nested dependency contains the lock. Logging objects, sessions, and framework components often carry synchronization primitives internally.
Another issue is passing instance methods to a process pool. That silently serializes self, which may drag an RLock along with it.
Developers also sometimes try to serialize the lock intentionally, thinking it will preserve coordination across processes. It will not. Cross-process synchronization needs different primitives or architecture.
Finally, __getstate__ is useful, but do not use it to hide deeper design problems. If the object's meaning depends on live thread state, making it picklable may not actually make it safe.
Summary
- '
_thread.RLockobjects cannot be pickled because they represent live synchronization state, not serializable data.' - The error usually means some larger object being sent to another process contains a lock.
- The cleanest fix is to pass plain data instead of lock-bearing objects.
- If appropriate, exclude the lock from pickled state and recreate it in
__setstate__. - Reconsider whether you need processes at all if the design is heavily based on shared in-memory objects and locks.
Related reading
- Typescript - Wait for promise resolve before function return
- Typescript async/await cannot determine correct return type
- Uber-go/zap and kafka-go race condition
- UI5 performance parameters data-sap-ui-preload vs. data-sap-ui-async
- TypeError concat got multiple values for argument 'axis
- TypeError Could not build a TypeSpec with type KerasTensor
- TypeError Client is not a constructor - error at the latest version of kafka-node
- TypeError cli.init is not a function for react native
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.