On program exit, loguru attempts to delete log files following a retention policy. However, on Windows, when some of those log files still have open file handles on them, a PermissionError is raised and propagates unhandled causing an exception stack trace to bubble up, this also has the side effect of preventing other log files that have no open file handles on them (and thus could have been deleted during the retention policy sweep) from being deleted. I noticed this bug specifically when running a program that only retains 1 logfile in a centralized log directory. Sometimes I run multiple instances of this program that all log to the same directory hence the open file handle problem. Ideally each client when exiting just attempts to delete whatever it can rather than letting the exception bubble up and interrupt the retention deletion process
Here is a PoC, tested on Windows 11 with Python 3.14
import time
from loguru import logger
from loguru import logger
# Instance 1 starts up and keeps running, holding its log file open.
instance_1 = logger.add("app_{time}.log", retention=1)
logger.info("Instance 1 is running")
time.sleep(1) # Give the two instances distinct timestamps.
# Instance 2 starts up later, then exits almost immediately.
instance_2 = logger.add("app_{time}.log", retention=1)
# Instance 2 exits. Retention keeps the newest file (instance 2's own, now
# closed) and deletes the older one but instance 1 still has that one open.
logger.remove(instance_2) # PermissionError: [WinError 32]
This is the output on my machine
$ uv run python -c "import loguru; print(loguru.__version__)"
0.7.3
$ cat .\test.py
import time
from loguru import logger
from loguru import logger
# Instance 1 starts up and keeps running, holding its log file open.
instance_1 = logger.add("app_{time}.log", retention=1)
logger.info("Instance 1 is running")
time.sleep(1) # Give the two instances distinct timestamps.
# Instance 2 starts up later, then exits almost immediately.
instance_2 = logger.add("app_{time}.log", retention=1)
# Instance 2 exits. Retention keeps the newest file (instance 2's own, now
# closed) and deletes the older one but instance 1 still has that one open.
logger.remove(instance_2) # PermissionError: [WinError 32]
$ uv run python .\test.py
2026-07-31 00:09:57.573 | INFO | __main__:<module>:10 - Instance 1 is running
Traceback (most recent call last):
File "C:\Users\sekiun\loguru_test\test.py", line 19, in <module>
logger.remove(instance_2) # PermissionError: [WinError 32]
~~~~~~~~~~~~~^^^^^^^^^^^^
File "C:\Users\sekiun\loguru_test\.venv\Lib\site-packages\loguru\_logger.py", line 1066, in remove
handler.stop()
~~~~~~~~~~~~^^
File "C:\Users\sekiun\loguru_test\.venv\Lib\site-packages\loguru\_handler.py", line 223, in stop
self._sink.stop()
~~~~~~~~~~~~~~~^^
File "C:\Users\sekiun\loguru_test\.venv\Lib\site-packages\loguru\_file_sink.py", line 212, in stop
self._terminate_file(is_rotating=False)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
File "C:\Users\sekiun\loguru_test\.venv\Lib\site-packages\loguru\_file_sink.py", line 290, in _terminate_file
self._retention_function(list(logs))
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "C:\Users\sekiun\loguru_test\.venv\Lib\site-packages\loguru\_file_sink.py", line 77, in retention_count
os.remove(log)
~~~~~~~~~^^^^^
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'app_2026-07-31_00-09-57_573000.log'
On program exit, loguru attempts to delete log files following a retention policy. However, on Windows, when some of those log files still have open file handles on them, a
PermissionErroris raised and propagates unhandled causing an exception stack trace to bubble up, this also has the side effect of preventing other log files that have no open file handles on them (and thus could have been deleted during the retention policy sweep) from being deleted. I noticed this bug specifically when running a program that only retains 1 logfile in a centralized log directory. Sometimes I run multiple instances of this program that all log to the same directory hence the open file handle problem. Ideally each client when exiting just attempts to delete whatever it can rather than letting the exception bubble up and interrupt the retention deletion processHere is a PoC, tested on Windows 11 with Python 3.14
This is the output on my machine