Netbox querying LDAP without credentials after session has been created #11421

Open
opened 2025-12-29 21:45:02 +01:00 by adam · 2 comments
Owner

Originally created by @MrPikPik on GitHub (Jul 29, 2025).

Deployment Type

Self-hosted (Docker)

NetBox Version

v4.3.4-Docker-3.3.0

Python Version

3.12.2

Steps to Reproduce

  • Log into Netbox using LDAP
  • Close Netbox tab(s)
  • Wait approximately 1 hour without activity in Netbox
  • Try to open Netbox again

Expected Behavior

  • A user having a valid session being able to use Netbox as usual
  • If a session has expired, invalidate session cookie and redirect to login page

We're using the LDAP Backend as described in the documentation to authenticate against a UCS LDAP, using the authenticating user as the bind user (AUTH_LDAP_BIND_AS_AUTHENTICATING_USER=true). Login, groups and permissions work completely normal and as configured, however after being inactive for some time (seems to be ~1h) and revisiting the web page users get the error:

<class 'ldap.OPERATIONS_ERROR'>

{'msgtype': 101, 'msgid': 2, 'result': 1, 'desc': 'Operations error', 'ctrls': [], 'info': '00002020: Operation unavailable without authentication'}

Checking the logs, it seems Netbox (or more specifically Django's LDAP backend) tries to authenticate to the LDAP again, but this time without credentials (since those are only given upon initial login) which fails:

Binding as 
Invoking search_s('CN=Groups,DC=work,DC=place', 2, '(&(objectclass=group)(member=CN=myusername,CN=Users,DC=work,DC=place))')
Internal Server Error: /
Traceback (most recent call last):
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/utilities/views.py", line 39, in dispatch
    return super().dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/netbox/views/misc.py", line 62, in get
    return render(request, self.template_name, {
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/shortcuts.py", line 25, in render
    content = loader.render_to_string(template_name, context, request, using=using)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
    return self.template.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/test/utils.py", line 114, in instrumented_test_render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
    return compiled_parent._render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/test/utils.py", line 114, in instrumented_test_render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
    return compiled_parent._render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/test/utils.py", line 114, in instrumented_test_render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
    result = block.nodelist.render(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/library.py", line 359, in render
    _dict = self.func(*resolved_args, **resolved_kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/utilities/templatetags/navigation.py", line 31, in nav
    if not user.has_perms(item.permissions):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 415, in has_perms
    return all(self.has_perm(perm, obj) for perm in perm_list)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 415, in <genexpr>
    return all(self.has_perm(perm, obj) for perm in perm_list)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 397, in has_perm
    return _user_has_perm(self, perm, obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 269, in _user_has_perm
    if backend.has_perm(user, perm, obj):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 124, in has_perm
    object_permissions = self.get_all_permissions(user_obj)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 72, in get_all_permissions
    user_obj._object_perm_cache = self.get_object_permissions(user_obj)
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 96, in get_object_permissions
    self.get_permission_filter(user_obj),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 324, in get_permission_filter
    hasattr(user_obj.ldap_user, "group_names")):
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/backend.py", line 471, in group_names
    return self._get_groups().get_group_names()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/backend.py", line 949, in get_group_names
    group_infos = self._get_group_infos()
                  ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/backend.py", line 996, in _get_group_infos
    self._group_infos = self._group_type.user_groups(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/config.py", line 536, in user_groups
    return search.execute(ldap_user.connection)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/config.py", line 204, in execute
    results = connection.search_s(
              ^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 631, in search_s
    return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 625, in search_ext_s
    return self.result(msgid,all=1,timeout=timeout)[1]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 535, in result
    resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 539, in result2
    resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 543, in result3
    resp_type, resp_data, resp_msgid, decoded_resp_ctrls, retoid, retval = self.result4(
                                                                           ^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 553, in result4
    ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 128, in _ldap_call
    result = func(*args,**kwargs)
             ^^^^^^^^^^^^^^^^^^^^
ldap.OPERATIONS_ERROR: {'msgtype': 101, 'msgid': 2, 'result': 1, 'desc': 'Operations error', 'ctrls': [], 'info': '00002020: Operation unavailable without authentication'}

We think that in this case Netbox probably should ignore the error and invalidate the given user's session and redirecting them to the login page.

Workaround

Our current workaround is deleting the sessionid Cookie or using the "Forget this website" feature of browsers since this forces a clean session.

Originally created by @MrPikPik on GitHub (Jul 29, 2025). ### Deployment Type Self-hosted (Docker) ### NetBox Version v4.3.4-Docker-3.3.0 ### Python Version 3.12.2 ### Steps to Reproduce - Log into Netbox using LDAP - Close Netbox tab(s) - Wait approximately 1 hour without activity in Netbox - Try to open Netbox again ### Expected Behavior - A user having a valid session being able to use Netbox as usual - If a session has expired, invalidate session cookie and redirect to login page We're using the [LDAP Backend as described in the documentation](https://netboxlabs.com/docs/netbox/installation/ldap/) to authenticate against a UCS LDAP, using the authenticating user as the bind user (`AUTH_LDAP_BIND_AS_AUTHENTICATING_USER=true`). Login, groups and permissions work completely normal and as configured, however after being inactive for some time (seems to be ~1h) and revisiting the web page users get the error: ``` <class 'ldap.OPERATIONS_ERROR'> {'msgtype': 101, 'msgid': 2, 'result': 1, 'desc': 'Operations error', 'ctrls': [], 'info': '00002020: Operation unavailable without authentication'} ``` Checking the logs, it seems Netbox (or more specifically Django's LDAP backend) tries to authenticate to the LDAP again, but this time without credentials (since those are only given upon initial login) which fails: ``` Binding as Invoking search_s('CN=Groups,DC=work,DC=place', 2, '(&(objectclass=group)(member=CN=myusername,CN=Users,DC=work,DC=place))') Internal Server Error: / Traceback (most recent call last): File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/utilities/views.py", line 39, in dispatch return super().dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch return handler(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/netbox/views/misc.py", line 62, in get return render(request, self.template_name, { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/shortcuts.py", line 25, in render content = loader.render_to_string(template_name, context, request, using=using) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader.py", line 62, in render_to_string return template.render(context, request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render return self.template.render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render return self._render(context) ^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/test/utils.py", line 114, in instrumented_test_render return self.nodelist.render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render return SafeString("".join([node.render_annotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated return self.render(context) ^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render return compiled_parent._render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/test/utils.py", line 114, in instrumented_test_render return self.nodelist.render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render return SafeString("".join([node.render_annotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated return self.render(context) ^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render return compiled_parent._render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/test/utils.py", line 114, in instrumented_test_render return self.nodelist.render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render return SafeString("".join([node.render_annotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated return self.render(context) ^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render result = block.nodelist.render(context) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render return SafeString("".join([node.render_annotated(context) for node in self])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated return self.render(context) ^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/template/library.py", line 359, in render _dict = self.func(*resolved_args, **resolved_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/utilities/templatetags/navigation.py", line 31, in nav if not user.has_perms(item.permissions): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 415, in has_perms return all(self.has_perm(perm, obj) for perm in perm_list) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 415, in <genexpr> return all(self.has_perm(perm, obj) for perm in perm_list) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 397, in has_perm return _user_has_perm(self, perm, obj) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django/contrib/auth/models.py", line 269, in _user_has_perm if backend.has_perm(user, perm, obj): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 124, in has_perm object_permissions = self.get_all_permissions(user_obj) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 72, in get_all_permissions user_obj._object_perm_cache = self.get_object_permissions(user_obj) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 96, in get_object_permissions self.get_permission_filter(user_obj), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/netbox/netbox/authentication/__init__.py", line 324, in get_permission_filter hasattr(user_obj.ldap_user, "group_names")): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/backend.py", line 471, in group_names return self._get_groups().get_group_names() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/backend.py", line 949, in get_group_names group_infos = self._get_group_infos() ^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/backend.py", line 996, in _get_group_infos self._group_infos = self._group_type.user_groups( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/config.py", line 536, in user_groups return search.execute(ldap_user.connection) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/django_auth_ldap/config.py", line 204, in execute results = connection.search_s( ^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 631, in search_s return self.search_ext_s(base,scope,filterstr,attrlist,attrsonly,None,None,timeout=self.timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 625, in search_ext_s return self.result(msgid,all=1,timeout=timeout)[1] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 535, in result resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 539, in result2 resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 543, in result3 resp_type, resp_data, resp_msgid, decoded_resp_ctrls, retoid, retval = self.result4( ^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 553, in result4 ldap_result = self._ldap_call(self._l.result4,msgid,all,timeout,add_ctrls,add_intermediates,add_extop) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/netbox/venv/lib/python3.12/site-packages/ldap/ldapobject.py", line 128, in _ldap_call result = func(*args,**kwargs) ^^^^^^^^^^^^^^^^^^^^ ldap.OPERATIONS_ERROR: {'msgtype': 101, 'msgid': 2, 'result': 1, 'desc': 'Operations error', 'ctrls': [], 'info': '00002020: Operation unavailable without authentication'} ``` We think that in this case Netbox probably should ignore the error and invalidate the given user's session and redirecting them to the login page. ### Workaround Our current workaround is deleting the `sessionid` Cookie or using the "Forget this website" feature of browsers since this forces a clean session.
adam added the type: bugstatus: needs ownernetboxseverity: low labels 2025-12-29 21:45:02 +01:00
Author
Owner

@jnovinger commented on GitHub (Aug 1, 2025):

Thank you for opening this detailed bug report with clear reproduction steps and stack trace, @MrPikPik .

This issue has a high barrier for maintainers to reproduce due to the specific LDAP configuration requirements. We'd appreciate any feedback from community members who have experience with similar LDAP setups.

We're moving this to "under review" status to allow time for additional input.

@jnovinger commented on GitHub (Aug 1, 2025): Thank you for opening this detailed bug report with clear reproduction steps and stack trace, @MrPikPik . This issue has a high barrier for maintainers to reproduce due to the specific LDAP configuration requirements. We'd appreciate any feedback from community members who have experience with similar LDAP setups. We're moving this to "under review" status to allow time for additional input.
Author
Owner

@MrPikPik commented on GitHub (Aug 6, 2025):

In the meantime we found two new ways to work around the issue:

1. Set AUTH_LDAP_FIND_GROUP_PERMS to false

This option is true by default in the official Docker image.
If I understand it correctly, if set to false Netbox won't refresh groups from LDAP on every request but only on first login (which is fine in our case, since group membership in regards to Netbox is static).

2. Reduce session lifetime

In case AUTH_LDAP_FIND_GROUP_PERMS needs to be true, reducing the session lifetime to be lower or equal to AUTH_LDAP_CACHE_TIMEOUT mitigates the issue. However having to log back in that often wasn't really an option for us. Alternatively increasing AUTH_LDAP_CACHE_TIMEOUT from the Docker image's default may also not be the greatest idea.

@MrPikPik commented on GitHub (Aug 6, 2025): In the meantime we found two new ways to work around the issue: ### 1. Set `AUTH_LDAP_FIND_GROUP_PERMS` to false This option is `true` by default in the [official Docker image](https://github.com/netbox-community/netbox-docker/blob/477decd80af739e1eaa03c20a9ccd3ddd699818a/configuration/ldap/ldap_config.py#L100). If I understand it correctly, if set to `false` Netbox won't refresh groups from LDAP on every request but only on first login (which is fine in our case, since group membership in regards to Netbox is static). ### 2. Reduce session lifetime In case `AUTH_LDAP_FIND_GROUP_PERMS` needs to be `true`, reducing the session lifetime to be lower or equal to `AUTH_LDAP_CACHE_TIMEOUT` mitigates the issue. However having to log back in that often wasn't really an option for us. Alternatively increasing [`AUTH_LDAP_CACHE_TIMEOUT` from the Docker image's default](https://github.com/netbox-community/netbox-docker/blob/477decd80af739e1eaa03c20a9ccd3ddd699818a/configuration/ldap/ldap_config.py#L104) may also not be the greatest idea.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11421