Hi,
we've changed one of our software deployments to be Zitified instead of using Ziti Edge Tunnelers as before. Pretty cool as we can deploy via Ziti in Github Actions now! ![]()
Unfortunately we are getting the below errors which we didn't get while using ZET. Any ideas?
We're using openziti==1.5.0, Controller v1.6.12
2026-01-05 19:10:40,967 - ERROR - Exception in callback _SelectorTransport._add_reader(21, <bound method..., bufsize=0>>>)
handle: <Handle _SelectorTransport._add_reader(21, <bound method..., bufsize=0>>>)>
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 282, in _add_reader
key = self._selector.get_key(fd)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/selectors.py", line 192, in get_key
raise KeyError("{!r} is not registered".format(fileobj)) from None
KeyError: '21 is not registered'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 928, in _add_reader
self._loop._add_reader(fd, callback, *args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 284, in _add_reader
self._selector.register(fd, selectors.EVENT_READ,
File "/usr/local/lib/python3.12/selectors.py", line 359, in register
self._selector.register(key.fd, poller_events)
OSError: [Errno 9] Bad file descriptor
2026-01-05 19:10:40,968 - ERROR - Exception in callback _SelectorTransport._add_reader(23, <bound method..., bufsize=0>>>)
handle: <Handle _SelectorTransport._add_reader(23, <bound method..., bufsize=0>>>)>
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 282, in _add_reader
key = self._selector.get_key(fd)
^^^^^^^^^^^^^^^^^^^^^^^^^^
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 928, in _add_reader
self._loop._add_reader(fd, callback, *args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 284, in _add_reader
self._selector.register(fd, selectors.EVENT_READ,
File "/usr/local/lib/python3.12/selectors.py", line 359, in register
self._selector.register(key.fd, poller_events)
OSError: [Errno 9] Bad file descriptor
2026-01-05 19:10:40,972 - ERROR - Exception in callback _SelectorTransport._add_reader(29, <bound method..., bufsize=0>>>)
handle: <Handle _SelectorTransport._add_reader(29, <bound method..., bufsize=0>>>)>
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 282, in _add_reader
key = self._selector.get_key(fd)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/selectors.py", line 192, in get_key
raise KeyError("{!r} is not registered".format(fileobj)) from None
KeyError: '29 is not registered'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 928, in _add_reader
self._loop._add_reader(fd, callback, *args)
File "/usr/local/lib/python3.12/asyncio/selector_events.py", line 284, in _add_reader
self._selector.register(fd, selectors.EVENT_READ,
File "/usr/local/lib/python3.12/selectors.py", line 359, in register
self._selector.register(key.fd, poller_events)
OSError: [Errno 9] Bad file descriptor
The code we're using to monkeypatch:
import os
import tempfile
import openziti
class OpenZitiConnection:
def __init__(self):
self._identity_tmpfile = None
def load_ziti_identity_from_string(self, identity_json_str: str):
self._identity_tmpfile = tempfile.NamedTemporaryFile(mode="w+", delete=False)
self._identity_tmpfile.write(identity_json_str)
self._identity_tmpfile.flush()
ztx = openziti.load(self._identity_tmpfile.name)
return ztx
def init_ziti_from_config(self, host: str, port: str) -> None:
ztx = self.load_ziti_identity_from_string(
os.environ.get("USECASE_DEPLOYMENT_ZITI_IDENTITY_JSON")
)
bindings = {
(host, port): {
"ztx": ztx,
}
}
openziti.monkeypatch(bindings=bindings)
def init_ziti_from_config_multi(self, bindings: dict) -> None:
ztx = self.load_ziti_identity_from_string(
os.environ.get("USECASE_DEPLOYMENT_ZITI_IDENTITY_JSON")
)
for addr in bindings:
bindings[addr]["ztx"] = ztx
openziti.monkeypatch(bindings=bindings)
Thanks
Dominik