You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] CRITICAL LookupError: unknown error handler name 'reversible' during hash cracking on Windows (multiprocessing spawn) #6143
While dumping a table that contains MD5 password hashes, sqlmap automatically starts
dictionary-based cracking in 16 parallel processes. On Windows, every worker emits a
CRITICAL log for each dictionary entry it processes:
[CRITICAL] there was a problem while hashing entry: 'abc123' ('LookupError: unknown error handler name 'reversible''). Please report by e-mail to 'dev@sqlmap.org'
[CRITICAL] there was a problem while hashing entry: 'charley' ('LookupError: unknown error handler name 'reversible'') ...
[CRITICAL] there was a problem while hashing entry: 'letmein' ('LookupError: unknown error handler name 'reversible'') ...
[CRITICAL] there was a problem while hashing entry: 'password' ('LookupError: unknown error handler name 'reversible'') ...
The dump and the cracking itself still complete correctly (plaintexts are recovered), so this is non-fatal, but the CRITICAL messages are misleading (they suggest a total failure when in fact
the data and even the cracked hashes are returned).
Root cause (analysis)
lib/core/patch.py (around lines 140-147) registers a custom codec error handler:
codecs.register_error("reversible", _reversible)
This registration happens once, inside dirtyPatches(), in the main process at startup.
The password-cracking code uses multiprocessing. On Windows, the spawn start method creates
brand-new interpreter processes that do not re-execute dirtyPatches(), so the "reversible"
error handler is not registered in the workers. When a worker calls getUnicode() / openFile()
with errors="reversible" (e.g. lib/core/convert.py:581 and lib/core/common.py:4022),
Python raises:
LookupError: unknown error handler name 'reversible'
On Linux, multiprocessing uses fork, so workers inherit the already-registered handler and the
bug does not appear. It is therefore Windows-specific.
Possibly related: #6122 (a similar worker-side patch/attribute error during hash cracking on
Windows, but a different exception).
Suggested fix
Register the "reversible" codec error handler in the multiprocessing worker initializer
(call codecs.register_error in the child init function), or
Ensure dirtyPatches() is executed at worker startup / module import so the handler exists in
spawned children, or
Guard the registration so it is re-applied when children are spawned.
Workaround
Run with --answers="crack=n" to skip cracking (no CRITICAL spam), or
Run sqlmap on Linux / WSL (fork), where the issue does not occur.
Environment: Windows 11, Python 3.10.11, sqlmap 1.10.10. The default multiprocessing start method on Windows is spawn.
reversible_repro.py:
importcodecsimportmultiprocessingasmpdef_reversible(ex):
# Same shape as sqlmap's handler in lib/core/patch.pyreturn (u"", ex.end)
defcheck(_):
try:
codecs.lookup_error("reversible")
return"OK: 'reversible' handler found"exceptLookupErrorase:
return"FAIL: LookupError: %s"%eif__name__=="__main__":
# sqlmap registers this once in the main process via dirtyPatches()codecs.register_error("reversible", _reversible)
print("start method :", mp.get_start_method())
print("Main process :", check(None))
withmp.Pool(2) aspool:
print("Worker procs :", pool.map(check, [0, 1]))
Output on Windows:
start method : spawn
Main process : OK: 'reversible' handler found
Worker procs : ["FAIL: LookupError: unknown error handler name 'reversible'", "FAIL: LookupError: unknown error handler name 'reversible'"]
Conclusion
codecs.register_error("reversible", ...) is called only in the main process (as dirtyPatches() does at startup). Because Windows multiprocessing uses spawn, the child worker processes start fresh and never re-run that registration, so the hash-cracking workers raise:
LookupError: unknown error handler name 'reversible'
On Linux, fork makes workers inherit the registration, which is why the bug is Windows-specific.
Suggested fix
Register the "reversible" codec error handler inside the multiprocessing worker initializer (or otherwise ensure dirtyPatches() is executed at worker startup), so spawned children have the handler registered.
Note
The bug is non-fatal: the dump and the hash cracking still complete (plaintexts are recovered); only the misleading [CRITICAL] messages are emitted per dictionary entry.
Activity
Scj752 commentedon Oct 11, 2026
Minimal reproducer (confirms the root cause)
Environment: Windows 11, Python 3.10.11, sqlmap 1.10.10. The default multiprocessing start method on Windows is
spawn.reversible_repro.py:Output on Windows:
Conclusion
codecs.register_error("reversible", ...)is called only in the main process (asdirtyPatches()does at startup). Because Windows multiprocessing usesspawn, the child worker processes start fresh and never re-run that registration, so the hash-cracking workers raise:On Linux,
forkmakes workers inherit the registration, which is why the bug is Windows-specific.Suggested fix
Register the
"reversible"codec error handler inside the multiprocessing worker initializer (or otherwise ensuredirtyPatches()is executed at worker startup), so spawned children have the handler registered.Note
The bug is non-fatal: the dump and the hash cracking still complete (plaintexts are recovered); only the misleading
[CRITICAL]messages are emitted per dictionary entry.stamparm commentedon Oct 11, 2026
thank you for excellent report
Fixes sqlmapproject#6143