[GH-ISSUE #3725] Calendar error: Modoboa 2.5.1 on fresh Bookworm 12 #1889

Closed
opened 2026-02-27 11:19:44 +03:00 by kerem · 6 comments
Owner

Originally created by @nadihighlander on GitHub (Sep 15, 2025).
Original GitHub issue: https://github.com/modoboa/modoboa/issues/3725

Impacted versions

  • OS Type: Debian 12
  • OS Version: Bookworm Linux version 6.1.0-39-amd64 (debian-kernel@lists.debian.org) (gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Debian 6.1.148-1 (2025-08-26)
  • Database Type: PostgreSQL
  • Database version: Last updated (by installer)
  • Modoboa: 2.5.1
  • installer used: Yes
  • Webserver: Nginx

Steps to reproduce

Install modoboa 5.2.1 on fresh system

Current behavior

Calendar event does not created properly and show error

Expected behavior

Creating calendar event without error

Video/Screenshot link (optional)

Originally created by @nadihighlander on GitHub (Sep 15, 2025). Original GitHub issue: https://github.com/modoboa/modoboa/issues/3725 # Impacted versions * OS Type: Debian 12 * OS Version: Bookworm Linux version 6.1.0-39-amd64 (debian-kernel@lists.debian.org) (gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT_DYNAMIC Debian 6.1.148-1 (2025-08-26) * Database Type: PostgreSQL * Database version: Last updated (by installer) * Modoboa: 2.5.1 * installer used: Yes * Webserver: Nginx # Steps to reproduce Install modoboa 5.2.1 on fresh system # Current behavior Calendar event does not created properly and show error <!-- PutError at /api/v2/user-calendars/3/events/ PutError at '409 Conflict Conflict in the request.', reason no reason Request Method: POST Request URL: https://mail.test.com/api/v2/user-calendars/3/events/ Django Version: 5.2.6 Exception Type: PutError Exception Value: PutError at '409 Conflict Conflict in the request.', reason no reason Exception Location: /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 772, in _put Raised during: modoboa.calendars.viewsets.UserEventViewSet Python Executable: /usr/bin/uwsgi-core Python Version: 3.11.2 Python Path: ['.', '', '/usr/lib/python311.zip', '/usr/lib/python3.11', '/usr/lib/python3.11/lib-dynload', '/srv/modoboa/env/lib/python3.11/site-packages'] Server time: Mon, 15 Sep 2025 14:10:57 +0330 Traceback Switch to copy-and-paste view /srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/exception.py, line 55, in inner return inner else: @wraps(get_response) def inner(request): try: response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ … except Exception as exc: response = response_for_exception(request, exc) return response return inner Local vars /srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/base.py, line 197, in _get_response if response is None: wrapped_callback = self.make_view_atomic(callback) # If it is an asynchronous view, run it in a subthread. if iscoroutinefunction(wrapped_callback): wrapped_callback = async_to_sync(wrapped_callback) try: response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … except Exception as e: response = self.process_exception_by_middleware(e, request) if response is None: raise # Complain if the view returned None (a common error). Local vars /usr/lib/python3.11/contextlib.py, line 81, in inner """ return self def __call__(self, func): @wraps(func) def inner(*args, **kwds): with self._recreate_cm(): return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ … return inner class AsyncContextDecorator(object): "A base class or mixin that enables async context managers to work as decorators." Local vars /usr/lib/python3.11/contextlib.py, line 81, in inner """ return self def __call__(self, func): @wraps(func) def inner(*args, **kwds): with self._recreate_cm(): return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ … return inner class AsyncContextDecorator(object): "A base class or mixin that enables async context managers to work as decorators." Local vars /srv/modoboa/env/lib/python3.11/site-packages/django/views/decorators/csrf.py, line 65, in _view_wrapper async def _view_wrapper(request, *args, **kwargs): return await view_func(request, *args, **kwargs) else: def _view_wrapper(request, *args, **kwargs): return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … _view_wrapper.csrf_exempt = True return wraps(view_func)(_view_wrapper) Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/viewsets.py, line 125, in view setattr(self, method, handler) self.request = request self.args = args self.kwargs = kwargs # And continue as usual return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 515, in dispatch self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^ … self.response = self.finalize_response(request, response, *args, **kwargs) return self.response def options(self, request, *args, **kwargs): """ Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 475, in handle_exception exception_handler = self.get_exception_handler() context = self.get_exception_handler_context() response = exception_handler(exc, context) if response is None: self.raise_uncaught_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … response.exception = True return response def raise_uncaught_exception(self, exc): if settings.DEBUG: Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 486, in raise_uncaught_exception def raise_uncaught_exception(self, exc): if settings.DEBUG: request = self.request renderer_format = getattr(request.accepted_renderer, 'format') use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin') request.force_plaintext_errors(use_plaintext_traceback) raise exc ^^^^^^^^^ … # Note: Views are made CSRF exempt from within `as_view` as to prevent # accidental removal of this exemption in cases where `dispatch` needs to # be overridden. def dispatch(self, request, *args, **kwargs): """ Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 512, in dispatch # Get the appropriate handler method if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … except Exception as exc: response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response Local vars /srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/viewsets.py, line 121, in create """ """Create new event.""" serializer = self.get_serializer() serializer.is_valid(raise_exception=True) backend = backends.get_backend_from_request( "caldav_", request, serializer.validated_data["calendar"] ) uid = backend.create_event(serializer.validated_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … event = dict(serializer.validated_data) calendar = serializer.validated_data["calendar"] event["id"] = uid event["color"] = calendar.color event["calendar"] = {"pk": calendar.pk} if self.type == "shared": Local vars /srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/backends/caldav_.py, line 91, in create_event cal.vevent.add("summary").value = data["title"] if not data["allDay"]: cal.vevent.add("dtstart").value = data["start"] cal.vevent.add("dtend").value = data["end"] else: cal.vevent.add("dtstart").value = data["start"].date() cal.vevent.add("dtend").value = data["end"].date() self.remote_cal.add_event(cal) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … return uid def update_event(self, uid, original_data): """Update an existing event.""" data = dict(original_data) url = f"{self.remote_cal.url.geturl()}/{uid}.ics" Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py, line 553, in save_event return o ## TODO: maybe we should deprecate those three def save_event(self, *largs, **kwargs) -> "Event": """ Returns ``self.save_object(Event, ...)`` - see :class:`save_object` """ return self.save_object(Event, *largs, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … def save_todo(self, *largs, **kwargs) -> "Todo": """ Returns ``self.save_object(Todo, ...)`` - so see :class:`save_object` """ return self.save_object(Todo, *largs, **kwargs) Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py, line 540, in save_object o = objclass( self.client, data=self._use_or_create_ics( ical, objtype=f"V{objclass.__name__.upper()}", **ical_data ), parent=self, ) o = o.save(no_overwrite=no_overwrite, no_create=no_create) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … ## TODO: Saving nothing is currently giving an object with None as URL. ## This should probably be changed in some future version to raise an error ## See also CalendarObjectResource.save() if o.url is not None: o._handle_reverse_relations(fix=True) return o Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 1000, in save return obj.save(increase_seqno=increase_seqno) if "SEQUENCE" in self.icalendar_component: seqno = self.icalendar_component.pop("SEQUENCE", None) if seqno is not None: self.icalendar_component.add("SEQUENCE", seqno + 1) self._create(id=self.id, path=path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … return self def is_loaded(self): """Returns True if there exists data in the object. An object is considered not to be loaded if it contains no data but just the URL. Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 777, in _create return self._put(False) else: raise error.PutError(errmsg(r)) def _create(self, id=None, path=None, retry_on_failure=True) -> None: ## TODO: Find a better method name self._find_id_path(id=id, path=path) self._put() ^^^^^^^^^^^ … def _generate_url(self): ## See https://github.com/python-caldav/caldav/issues/143 for the rationale behind double-quoting slashes ## TODO: should try to wrap my head around issues that arises when id contains weird characters. maybe it's ## better to generate a new uuid here, particularly if id is in some unexpected format. if not self.id: Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 770, in _put import vobject except ImportError: retry_on_failure = False if retry_on_failure: ## This looks like a noop, but the object may be "cleaned". ## See https://github.com/python-caldav/caldav/issues/43 self.vobject_instance return self._put(False) ^^^^^^^^^^^^^^^^ … else: raise error.PutError(errmsg(r)) def _create(self, id=None, path=None, retry_on_failure=True) -> None: ## TODO: Find a better method name self._find_id_path(id=id, path=path) Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 772, in _put retry_on_failure = False if retry_on_failure: ## This looks like a noop, but the object may be "cleaned". ## See https://github.com/python-caldav/caldav/issues/43 self.vobject_instance return self._put(False) else: raise error.PutError(errmsg(r)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … def _create(self, id=None, path=None, retry_on_failure=True) -> None: ## TODO: Find a better method name self._find_id_path(id=id, path=path) self._put() Local vars Environment: Request Method: POST Request URL: https://mail.test.com/api/v2/user-calendars/3/events/ Django Version: 5.2.6 Python Version: 3.11.2 Installed Applications: ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.sites', 'django.contrib.staticfiles', 'reversion', 'oauth2_provider', 'corsheaders', 'rest_framework', 'rest_framework.authtoken', 'drf_spectacular', 'phonenumber_field', 'django_otp', 'django_otp.plugins.otp_totp', 'django_otp.plugins.otp_static', 'django_rename_app', 'django_rq', 'modoboa', 'modoboa.core', 'modoboa.lib', 'modoboa.admin', 'modoboa.transport', 'modoboa.relaydomains', 'modoboa.limits', 'modoboa.parameters', 'modoboa.dnstools', 'modoboa.policyd', 'modoboa.maillog', 'modoboa.pdfcredentials', 'modoboa.dmarc', 'modoboa.imap_migration', 'modoboa.autoreply', 'modoboa.sievefilters', 'modoboa.contacts', 'modoboa.calendars', 'modoboa.webmail', 'modoboa.amavis') Installed Middleware: ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'x_forwarded_for.middleware.XForwardedForMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'modoboa.core.middleware.LocalConfigMiddleware', 'modoboa.lib.middleware.CommonExceptionCatcher', 'modoboa.lib.middleware.RequestCatcherMiddleware') Traceback (most recent call last): File "/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/contextlib.py", line 81, in inner return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/contextlib.py", line 81, in inner return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/viewsets.py", line 125, in view return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 515, in dispatch response = self.handle_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 475, in handle_exception self.raise_uncaught_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception raise exc ^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 512, in dispatch response = handler(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/viewsets.py", line 121, in create uid = backend.create_event(serializer.validated_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/backends/caldav_.py", line 91, in create_event self.remote_cal.add_event(cal) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py", line 553, in save_event return self.save_object(Event, *largs, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py", line 540, in save_object o = o.save(no_overwrite=no_overwrite, no_create=no_create) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 1000, in save self._create(id=self.id, path=path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 777, in _create self._put() ^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 770, in _put return self._put(False) ^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 772, in _put raise error.PutError(errmsg(r)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Exception Type: PutError at /api/v2/user-calendars/3/events/ Exception Value: PutError at '409 Conflict Conflict in the request.', reason no reason Request information USER user1@test.com GET No GET data POST No POST data FILES No FILES data COOKIES Variable Value SERVERID 'cookie1' django_language 'en' csrftoken '********************' sessionid '********************' META Variable Value CONTENT_LENGTH '99' CONTENT_TYPE 'application/json' CSRF_COOKIE 'deCK5OirJMkzeftzssFakEvbw2v58eOW' DOCUMENT_ROOT '/srv/modoboa/instance' HTTP_ACCEPT 'application/json, text/plain, */*' HTTP_ACCEPT_ENCODING 'gzip, deflate, br, zstd' HTTP_ACCEPT_LANGUAGE 'en' HTTP_AUTHORIZATION '********************' HTTP_CONTENT_LENGTH '99' HTTP_CONTENT_TYPE 'application/json' HTTP_COOKIE '********************' HTTP_DNT '1' HTTP_HOST 'mail.test.com' HTTP_ORIGIN 'https://mail.test.com' HTTP_REFERER 'https://mail.test.com/user/calendars' HTTP_SEC_CH_UA '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"' HTTP_SEC_CH_UA_MOBILE '?0' HTTP_SEC_CH_UA_PLATFORM '"Windows"' HTTP_SEC_FETCH_DEST 'empty' HTTP_SEC_FETCH_MODE 'cors' HTTP_SEC_FETCH_SITE 'same-origin' HTTP_USER_AGENT ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like ' 'Gecko) Chrome/140.0.0.0 Safari/537.36') HTTP_X_FORWARDED_FOR '5.239.172.182' HTTP_X_FORWARDED_PORT '443' HTTP_X_FORWARDED_PROTO 'https' PATH_INFO '/api/v2/user-calendars/3/events/' QUERY_STRING '' REMOTE_ADDR '5.239.172.182' REMOTE_PORT '45062' REQUEST_METHOD 'POST' REQUEST_SCHEME 'http' REQUEST_URI '/api/v2/user-calendars/3/events/' SCRIPT_NAME '' SERVER_NAME 'mail.test.com' SERVER_PORT '801' SERVER_PROTOCOL 'HTTP/1.1' UWSGI_APPID 'mail.test.com|' UWSGI_SCRIPT 'instance.wsgi:application' uwsgi.node b'modolast' uwsgi.version b'2.0.21-debian' wsgi.errors <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'> wsgi.file_wrapper <built-in function uwsgi_sendfile> wsgi.input <uwsgi._Input object at 0x7f2b35711930> wsgi.multiprocess True wsgi.multithread False wsgi.run_once False wsgi.url_scheme 'https' wsgi.version (1, 0) Settings Using settings module instance.settings Setting Value ABSOLUTE_URL_OVERRIDES {} ADMINS [] ALLOWED_HOSTS ['mail.test.com'] AMAVIS_DEFAULT_DATABASE_ENCODING 'LATIN1' APPEND_SLASH True AUTHENTICATION_BACKENDS '********************' AUTH_PASSWORD_VALIDATORS '********************' AUTH_USER_MODEL '********************' BASE_DIR '/srv/modoboa/instance' CACHES {'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://localhost:6379/0'}} CACHE_MIDDLEWARE_ALIAS 'default' CACHE_MIDDLEWARE_KEY_PREFIX '********************' CACHE_MIDDLEWARE_SECONDS 600 CSRF_COOKIE_AGE 31449600 CSRF_COOKIE_DOMAIN None CSRF_COOKIE_HTTPONLY False CSRF_COOKIE_NAME 'csrftoken' CSRF_COOKIE_PATH '/' CSRF_COOKIE_SAMESITE 'Lax' CSRF_COOKIE_SECURE True CSRF_FAILURE_VIEW 'django.views.csrf.csrf_failure' CSRF_HEADER_NAME 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS [] CSRF_USE_SESSIONS False DATABASES {'amavis': {'ATOMIC_REQUESTS': True, 'AUTOCOMMIT': True, 'CONN_HEALTH_CHECKS': False, 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.postgresql', 'HOST': '127.0.0.1', 'NAME': 'amavis', 'OPTIONS': {}, 'PASSWORD': '********************', 'PORT': '5432', 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None}, 'TIME_ZONE': None, 'USER': 'amavis'}, 'default': {'ATOMIC_REQUESTS': True, 'AUTOCOMMIT': True, 'CONN_HEALTH_CHECKS': False, 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.postgresql', 'HOST': '127.0.0.1', 'NAME': 'modoboa', 'OPTIONS': {}, 'PASSWORD': '********************', 'PORT': '5432', 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None}, 'TIME_ZONE': None, 'USER': 'modoboa'}} DATABASE_ROUTERS ['modoboa.amavis.dbrouter.AmavisRouter'] DATA_UPLOAD_MAX_MEMORY_SIZE 2621440 DATA_UPLOAD_MAX_NUMBER_FIELDS 1000 DATA_UPLOAD_MAX_NUMBER_FILES 100 DATETIME_FORMAT 'N j, Y, P' DATETIME_INPUT_FORMATS ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M'] DATE_FORMAT 'N j, Y' DATE_INPUT_FORMATS ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y'] DEBUG True DEBUG_PROPAGATE_EXCEPTIONS False DECIMAL_SEPARATOR '.' DEFAULT_AUTO_FIELD 'django.db.models.AutoField' DEFAULT_CHARSET 'utf-8' DEFAULT_EXCEPTION_REPORTER 'django.views.debug.ExceptionReporter' DEFAULT_EXCEPTION_REPORTER_FILTER 'django.views.debug.SafeExceptionReporterFilter' DEFAULT_FROM_EMAIL 'webmaster@localhost' DEFAULT_INDEX_TABLESPACE '' DEFAULT_TABLESPACE '' DISABLE_DASHBOARD_EXTERNAL_QUERIES False DISALLOWED_USER_AGENTS [] EMAIL_BACKEND 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST 'localhost' EMAIL_HOST_PASSWORD '********************' EMAIL_HOST_USER '' EMAIL_PORT 25 EMAIL_SSL_CERTFILE None EMAIL_SSL_KEYFILE '********************' EMAIL_SUBJECT_PREFIX '[Django] ' EMAIL_TIMEOUT None EMAIL_USE_LOCALTIME False EMAIL_USE_SSL False EMAIL_USE_TLS False FILE_UPLOAD_DIRECTORY_PERMISSIONS None FILE_UPLOAD_HANDLERS ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler'] FILE_UPLOAD_MAX_MEMORY_SIZE 2621440 FILE_UPLOAD_PERMISSIONS 420 FILE_UPLOAD_TEMP_DIR None FIRST_DAY_OF_WEEK 0 FIXTURE_DIRS [] FORCE_SCRIPT_NAME None FORMAT_MODULE_PATH None FORMS_URLFIELD_ASSUME_HTTPS False FORM_RENDERER 'django.forms.renderers.DjangoTemplates' IGNORABLE_404_URLS [] INSTALLED_APPS ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.sites', 'django.contrib.staticfiles', 'reversion', 'oauth2_provider', 'corsheaders', 'rest_framework', 'rest_framework.authtoken', 'drf_spectacular', 'phonenumber_field', 'django_otp', 'django_otp.plugins.otp_totp', 'django_otp.plugins.otp_static', 'django_rename_app', 'django_rq', 'modoboa', 'modoboa.core', 'modoboa.lib', 'modoboa.admin', 'modoboa.transport', 'modoboa.relaydomains', 'modoboa.limits', 'modoboa.parameters', 'modoboa.dnstools', 'modoboa.policyd', 'modoboa.maillog', 'modoboa.pdfcredentials', 'modoboa.dmarc', 'modoboa.imap_migration', 'modoboa.autoreply', 'modoboa.sievefilters', 'modoboa.contacts', 'modoboa.calendars', 'modoboa.webmail', 'modoboa.amavis') INTERNAL_IPS [] LANGUAGES [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ar-dz', 'Algerian Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('ckb', 'Central Kurdish (Sorani)'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('ig', 'Igbo'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('ky', 'Kyrgyz'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('ms', 'Malay'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('tg', 'Tajik'), ('th', 'Thai'), ('tk', 'Turkmen'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('ug', 'Uyghur'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('uz', 'Uzbek'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')] LANGUAGES_BIDI ['he', 'ar', 'ar-dz', 'ckb', 'fa', 'ug', 'ur'] LANGUAGE_CODE 'en' LANGUAGE_COOKIE_AGE None LANGUAGE_COOKIE_DOMAIN None LANGUAGE_COOKIE_HTTPONLY False LANGUAGE_COOKIE_NAME 'django_language' LANGUAGE_COOKIE_PATH '/' LANGUAGE_COOKIE_SAMESITE None LANGUAGE_COOKIE_SECURE False LOCALE_PATHS [] LOGGING {'formatters': {'syslog': {'format': '%(name)s: %(levelname)s %(message)s'}}, 'handlers': {'mail-admins': {'class': 'django.utils.log.AdminEmailHandler', 'include_html': True, 'level': 'ERROR'}, 'modoboa': {'class': 'modoboa.core.loggers.SQLHandler'}, 'syslog-auth': '********************', 'syslog-mail': {'class': 'logging.handlers.SysLogHandler', 'facility': 2, 'formatter': 'syslog'}}, 'loggers': {'django': {'handlers': ['mail-admins'], 'level': 'ERROR', 'propagate': False}, 'modoboa.admin': {'handlers': ['modoboa'], 'level': 'INFO', 'propagate': False}, 'modoboa.auth': '********************', 'modoboa.policyd': {'handlers': ['syslog-mail'], 'level': 'INFO', 'propagate': False}}, 'version': 1} LOGGING_CONFIG 'logging.config.dictConfig' LOGIN_REDIRECT_URL '/accounts/profile/' LOGIN_URL '/accounts/login/' LOGOUT_REDIRECT_URL None MANAGERS [] MEDIA_ROOT '/srv/modoboa/instance/media' MEDIA_URL '/media/' MESSAGE_STORAGE 'django.contrib.messages.storage.fallback.FallbackStorage' MIDDLEWARE ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'x_forwarded_for.middleware.XForwardedForMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'modoboa.core.middleware.LocalConfigMiddleware', 'modoboa.lib.middleware.CommonExceptionCatcher', 'modoboa.lib.middleware.RequestCatcherMiddleware') MIGRATION_MODULES {} MODOBOA_API_URL '********************' MODOBOA_APPS ('modoboa', 'modoboa.core', 'modoboa.lib', 'modoboa.admin', 'modoboa.transport', 'modoboa.relaydomains', 'modoboa.limits', 'modoboa.parameters', 'modoboa.dnstools', 'modoboa.policyd', 'modoboa.maillog', 'modoboa.pdfcredentials', 'modoboa.dmarc', 'modoboa.imap_migration', 'modoboa.autoreply', 'modoboa.sievefilters', 'modoboa.contacts', 'modoboa.calendars', 'modoboa.webmail', 'modoboa.amavis') MONTH_DAY_FORMAT 'F j' NUMBER_GROUPING 0 OAUTH2_PROVIDER '********************' OTP_TOTP_ISSUER 'mail.test.com' PASSWORD_HASHERS '********************' PASSWORD_RESET_TIMEOUT '********************' PHONENUMBER_DB_FORMAT 'INTERNATIONAL' PID_FILE_STORAGE_PATH '/var/run' PREPEND_WWW False REDIS_HOST 'localhost' REDIS_PORT 6379 REDIS_QUOTA_DB 0 REDIS_URL 'redis://localhost:6379/0' REST_FRAMEWORK {'DEFAULT_AUTHENTICATION_CLASSES': '********************', 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', 'DEFAULT_THROTTLE_RATES': {'ddos': '5/second', 'ddos_lesser': '200/minute', 'login': '10/minute', 'password_recovery_apply': '********************', 'password_recovery_request': '********************', 'password_recovery_totp_check': '********************', 'user': '300/minute'}, 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning'} ROOT_URLCONF 'instance.urls' RQ_QUEUES {'dkim': {'DB': 0, 'HOST': 'localhost', 'PORT': 6379, 'URL': 'redis://localhost:6379/0'}, 'modoboa': {'DB': 0, 'HOST': 'localhost', 'PORT': 6379, 'URL': 'redis://localhost:6379/0'}} SECRET_KEY '********************' SECRET_KEY_FALLBACKS '********************' SECURE_CONTENT_TYPE_NOSNIFF True SECURE_CROSS_ORIGIN_OPENER_POLICY 'same-origin' SECURE_HSTS_INCLUDE_SUBDOMAINS False SECURE_HSTS_PRELOAD False SECURE_HSTS_SECONDS 0 SECURE_PROXY_SSL_HEADER None SECURE_REDIRECT_EXEMPT [] SECURE_REFERRER_POLICY 'same-origin' SECURE_SSL_HOST None SECURE_SSL_REDIRECT False SERVER_EMAIL 'root@localhost' SESSION_CACHE_ALIAS 'default' SESSION_COOKIE_AGE 1209600 SESSION_COOKIE_DOMAIN None SESSION_COOKIE_HTTPONLY True SESSION_COOKIE_NAME 'sessionid' SESSION_COOKIE_PATH '/' SESSION_COOKIE_SAMESITE 'Lax' SESSION_COOKIE_SECURE True SESSION_ENGINE 'django.contrib.sessions.backends.db' SESSION_EXPIRE_AT_BROWSER_CLOSE False SESSION_FILE_PATH None SESSION_SAVE_EVERY_REQUEST False SESSION_SERIALIZER 'django.contrib.sessions.serializers.JSONSerializer' SETTINGS_MODULE 'instance.settings' SHORT_DATETIME_FORMAT 'm/d/Y P' SHORT_DATE_FORMAT 'm/d/Y' SIGNING_BACKEND 'django.core.signing.TimestampSigner' SILENCED_SYSTEM_CHECKS ['security.W019'] SITE_ID 1 SPECTACULAR_SETTINGS {'SCHEMA_PATH_PREFIX': '/api/v[0-9]', 'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'], 'TITLE': 'Modoboa API', 'VERSION': None} STATICFILES_DIRS [] STATICFILES_FINDERS ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder'] STATIC_ROOT '/srv/modoboa/instance/sitestatic' STATIC_URL '/sitestatic/' STORAGES {'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'}, 'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'}} TEMPLATES [{'APP_DIRS': True, 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages'], 'debug': False}}] TEST_NON_SERIALIZED_APPS [] TEST_RUNNER 'django.test.runner.DiscoverRunner' THOUSAND_SEPARATOR ',' TIME_FORMAT 'P' TIME_INPUT_FORMATS ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] TIME_ZONE 'Asia/Tehran' USE_I18N True USE_L10N True USE_THOUSAND_SEPARATOR False USE_TZ True USE_X_FORWARDED_HOST False USE_X_FORWARDED_PORT False WSGI_APPLICATION 'instance.wsgi.application' X_FRAME_OPTIONS 'SAMEORIGIN' YEAR_MONTH_FORMAT 'F Y' You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard page generated by the handler for this status code. --> # Expected behavior Creating calendar event without error # Video/Screenshot link (optional)
kerem closed this issue 2026-02-27 11:19:44 +03:00
Author
Owner

@nadihighlander commented on GitHub (Sep 15, 2025):

PutError at /api/v2/user-calendars/3/events/
PutError at '409 Conflict

Conflict in the request.', reason no reason
Request Method:	POST
Request URL:	https://mail.test.com/api/v2/user-calendars/3/events/
Django Version:	5.2.6
Exception Type:	PutError
Exception Value:	
PutError at '409 Conflict

Conflict in the request.', reason no reason
Exception Location:	/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 772, in _put
Raised during:	modoboa.calendars.viewsets.UserEventViewSet
Python Executable:	/usr/bin/uwsgi-core
Python Version:	3.11.2
Python Path:	
['.',
 '',
 '/usr/lib/python311.zip',
 '/usr/lib/python3.11',
 '/usr/lib/python3.11/lib-dynload',
 '/srv/modoboa/env/lib/python3.11/site-packages']
Server time:	Mon, 15 Sep 2025 14:10:57 +0330
Traceback Switch to copy-and-paste view
/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/exception.py, line 55, in inner
        return inner
    else:
        @wraps(get_response)
        def inner(request):
            try:
                response = get_response(request)
                               ^^^^^^^^^^^^^^^^^^^^^ …
            except Exception as exc:
                response = response_for_exception(request, exc)
            return response
        return inner
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/base.py, line 197, in _get_response
        if response is None:
            wrapped_callback = self.make_view_atomic(callback)
            # If it is an asynchronous view, run it in a subthread.
            if iscoroutinefunction(wrapped_callback):
                wrapped_callback = async_to_sync(wrapped_callback)
            try:
                response = wrapped_callback(request, *callback_args, **callback_kwargs)
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
            except Exception as e:
                response = self.process_exception_by_middleware(e, request)
                if response is None:
                    raise
        # Complain if the view returned None (a common error).
Local vars
/usr/lib/python3.11/contextlib.py, line 81, in inner
        """
        return self
    def __call__(self, func):
        @wraps(func)
        def inner(*args, **kwds):
            with self._recreate_cm():
                return func(*args, **kwds)
                           ^^^^^^^^^^^^^^^^^^^ …
        return inner
class AsyncContextDecorator(object):
    "A base class or mixin that enables async context managers to work as decorators."
Local vars
/usr/lib/python3.11/contextlib.py, line 81, in inner
        """
        return self
    def __call__(self, func):
        @wraps(func)
        def inner(*args, **kwds):
            with self._recreate_cm():
                return func(*args, **kwds)
                           ^^^^^^^^^^^^^^^^^^^ …
        return inner
class AsyncContextDecorator(object):
    "A base class or mixin that enables async context managers to work as decorators."
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/django/views/decorators/csrf.py, line 65, in _view_wrapper
        async def _view_wrapper(request, *args, **kwargs):
            return await view_func(request, *args, **kwargs)
    else:
        def _view_wrapper(request, *args, **kwargs):
            return view_func(request, *args, **kwargs)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
    _view_wrapper.csrf_exempt = True
    return wraps(view_func)(_view_wrapper)
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/viewsets.py, line 125, in view
                setattr(self, method, handler)
            self.request = request
            self.args = args
            self.kwargs = kwargs
            # And continue as usual
            return self.dispatch(request, *args, **kwargs)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        # take name and docstring from class
        update_wrapper(view, cls, updated=())
        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 515, in dispatch
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            response = handler(request, *args, **kwargs)
        except Exception as exc:
            response = self.handle_exception(exc)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
    def options(self, request, *args, **kwargs):
        """
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 475, in handle_exception
        exception_handler = self.get_exception_handler()
        context = self.get_exception_handler_context()
        response = exception_handler(exc, context)
        if response is None:
            self.raise_uncaught_exception(exc)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        response.exception = True
        return response
    def raise_uncaught_exception(self, exc):
        if settings.DEBUG:
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 486, in raise_uncaught_exception
    def raise_uncaught_exception(self, exc):
        if settings.DEBUG:
            request = self.request
            renderer_format = getattr(request.accepted_renderer, 'format')
            use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin')
            request.force_plaintext_errors(use_plaintext_traceback)
        raise exc
             ^^^^^^^^^ …
    # Note: Views are made CSRF exempt from within `as_view` as to prevent
    # accidental removal of this exemption in cases where `dispatch` needs to
    # be overridden.
    def dispatch(self, request, *args, **kwargs):
        """
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 512, in dispatch
            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            response = handler(request, *args, **kwargs)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        except Exception as exc:
            response = self.handle_exception(exc)
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/viewsets.py, line 121, in create
        """
        """Create new event."""
        serializer = self.get_serializer()
        serializer.is_valid(raise_exception=True)
        backend = backends.get_backend_from_request(
            "caldav_", request, serializer.validated_data["calendar"]
        )
        uid = backend.create_event(serializer.validated_data)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        event = dict(serializer.validated_data)
        calendar = serializer.validated_data["calendar"]
        event["id"] = uid
        event["color"] = calendar.color
        event["calendar"] = {"pk": calendar.pk}
        if self.type == "shared":
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/backends/caldav_.py, line 91, in create_event
        cal.vevent.add("summary").value = data["title"]
        if not data["allDay"]:
            cal.vevent.add("dtstart").value = data["start"]
            cal.vevent.add("dtend").value = data["end"]
        else:
            cal.vevent.add("dtstart").value = data["start"].date()
            cal.vevent.add("dtend").value = data["end"].date()
        self.remote_cal.add_event(cal)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        return uid
    def update_event(self, uid, original_data):
        """Update an existing event."""
        data = dict(original_data)
        url = f"{self.remote_cal.url.geturl()}/{uid}.ics"
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py, line 553, in save_event
        return o
    ## TODO: maybe we should deprecate those three
    def save_event(self, *largs, **kwargs) -> "Event":
        """
        Returns ``self.save_object(Event, ...)`` - see :class:`save_object`
        """
        return self.save_object(Event, *largs, **kwargs)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
    def save_todo(self, *largs, **kwargs) -> "Todo":
        """
        Returns ``self.save_object(Todo, ...)`` - so see :class:`save_object`
        """
        return self.save_object(Todo, *largs, **kwargs)
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py, line 540, in save_object
        o = objclass(
            self.client,
            data=self._use_or_create_ics(
                ical, objtype=f"V{objclass.__name__.upper()}", **ical_data
            ),
            parent=self,
        )
        o = o.save(no_overwrite=no_overwrite, no_create=no_create)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        ## TODO: Saving nothing is currently giving an object with None as URL.
        ## This should probably be changed in some future version to raise an error
        ## See also CalendarObjectResource.save()
        if o.url is not None:
            o._handle_reverse_relations(fix=True)
        return o
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 1000, in save
                return obj.save(increase_seqno=increase_seqno)
        if "SEQUENCE" in self.icalendar_component:
            seqno = self.icalendar_component.pop("SEQUENCE", None)
            if seqno is not None:
                self.icalendar_component.add("SEQUENCE", seqno + 1)
        self._create(id=self.id, path=path)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
        return self
    def is_loaded(self):
        """Returns True if there exists data in the object.  An
        object is considered not to be loaded if it contains no data
        but just the URL.
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 777, in _create
                return self._put(False)
            else:
                raise error.PutError(errmsg(r))
    def _create(self, id=None, path=None, retry_on_failure=True) -> None:
        ## TODO: Find a better method name
        self._find_id_path(id=id, path=path)
        self._put()
             ^^^^^^^^^^^ …
    def _generate_url(self):
        ## See https://github.com/python-caldav/caldav/issues/143 for the rationale behind double-quoting slashes
        ## TODO: should try to wrap my head around issues that arises when id contains weird characters.  maybe it's
        ## better to generate a new uuid here, particularly if id is in some unexpected format.
        if not self.id:
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 770, in _put
                    import vobject
                except ImportError:
                    retry_on_failure = False
            if retry_on_failure:
                ## This looks like a noop, but the object may be "cleaned".
                ## See https://github.com/python-caldav/caldav/issues/43
                self.vobject_instance
                return self._put(False)
                            ^^^^^^^^^^^^^^^^ …
            else:
                raise error.PutError(errmsg(r))
    def _create(self, id=None, path=None, retry_on_failure=True) -> None:
        ## TODO: Find a better method name
        self._find_id_path(id=id, path=path)
Local vars
/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 772, in _put
                    retry_on_failure = False
            if retry_on_failure:
                ## This looks like a noop, but the object may be "cleaned".
                ## See https://github.com/python-caldav/caldav/issues/43
                self.vobject_instance
                return self._put(False)
            else:
                raise error.PutError(errmsg(r))
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ …
    def _create(self, id=None, path=None, retry_on_failure=True) -> None:
        ## TODO: Find a better method name
        self._find_id_path(id=id, path=path)
        self._put()
Local vars
Environment:


Request Method: POST
Request URL: https://mail.test.com/api/v2/user-calendars/3/events/

Django Version: 5.2.6
Python Version: 3.11.2
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.sites',
 'django.contrib.staticfiles',
 'reversion',
 'oauth2_provider',
 'corsheaders',
 'rest_framework',
 'rest_framework.authtoken',
 'drf_spectacular',
 'phonenumber_field',
 'django_otp',
 'django_otp.plugins.otp_totp',
 'django_otp.plugins.otp_static',
 'django_rename_app',
 'django_rq',
 'modoboa',
 'modoboa.core',
 'modoboa.lib',
 'modoboa.admin',
 'modoboa.transport',
 'modoboa.relaydomains',
 'modoboa.limits',
 'modoboa.parameters',
 'modoboa.dnstools',
 'modoboa.policyd',
 'modoboa.maillog',
 'modoboa.pdfcredentials',
 'modoboa.dmarc',
 'modoboa.imap_migration',
 'modoboa.autoreply',
 'modoboa.sievefilters',
 'modoboa.contacts',
 'modoboa.calendars',
 'modoboa.webmail',
 'modoboa.amavis')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'x_forwarded_for.middleware.XForwardedForMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'modoboa.core.middleware.LocalConfigMiddleware',
 'modoboa.lib.middleware.CommonExceptionCatcher',
 'modoboa.lib.middleware.RequestCatcherMiddleware')



Traceback (most recent call last):
  File "/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 515, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 475, in handle_exception
    self.raise_uncaught_exception(exc)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception
    raise exc
    ^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 512, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/viewsets.py", line 121, in create
    uid = backend.create_event(serializer.validated_data)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/backends/caldav_.py", line 91, in create_event
    self.remote_cal.add_event(cal)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py", line 553, in save_event
    return self.save_object(Event, *largs, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py", line 540, in save_object
    o = o.save(no_overwrite=no_overwrite, no_create=no_create)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 1000, in save
    self._create(id=self.id, path=path)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 777, in _create
    self._put()
    ^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 770, in _put
    return self._put(False)
           ^^^^^^^^^^^^^^^^
  File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 772, in _put
    raise error.PutError(errmsg(r))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: PutError at /api/v2/user-calendars/3/events/
Exception Value: PutError at '409 Conflict

Conflict in the request.', reason no reason



Request information
USER
user1@test.com

GET
No GET data

POST
No POST data

FILES
No FILES data

COOKIES
Variable	Value
SERVERID	
'cookie1'
django_language	
'en'
csrftoken	
'********************'
sessionid	
'********************'
META
Variable	Value
CONTENT_LENGTH	
'99'
CONTENT_TYPE	
'application/json'
CSRF_COOKIE	
'deCK5OirJMkzeftzssFakEvbw2v58eOW'
DOCUMENT_ROOT	
'/srv/modoboa/instance'
HTTP_ACCEPT	
'application/json, text/plain, */*'
HTTP_ACCEPT_ENCODING	
'gzip, deflate, br, zstd'
HTTP_ACCEPT_LANGUAGE	
'en'
HTTP_AUTHORIZATION	
'********************'
HTTP_CONTENT_LENGTH	
'99'
HTTP_CONTENT_TYPE	
'application/json'
HTTP_COOKIE	
'********************'
HTTP_DNT	
'1'
HTTP_HOST	
'mail.test.com'
HTTP_ORIGIN	
'https://mail.test.com'
HTTP_REFERER	
'https://mail.test.com/user/calendars'
HTTP_SEC_CH_UA	
'"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"'
HTTP_SEC_CH_UA_MOBILE	
'?0'
HTTP_SEC_CH_UA_PLATFORM	
'"Windows"'
HTTP_SEC_FETCH_DEST	
'empty'
HTTP_SEC_FETCH_MODE	
'cors'
HTTP_SEC_FETCH_SITE	
'same-origin'
HTTP_USER_AGENT	
('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like '
 'Gecko) Chrome/140.0.0.0 Safari/537.36')
HTTP_X_FORWARDED_FOR	
'5.239.172.182'
HTTP_X_FORWARDED_PORT	
'443'
HTTP_X_FORWARDED_PROTO	
'https'
PATH_INFO	
'/api/v2/user-calendars/3/events/'
QUERY_STRING	
''
REMOTE_ADDR	
'5.239.172.182'
REMOTE_PORT	
'45062'
REQUEST_METHOD	
'POST'
REQUEST_SCHEME	
'http'
REQUEST_URI	
'/api/v2/user-calendars/3/events/'
SCRIPT_NAME	
''
SERVER_NAME	
'mail.test.com'
SERVER_PORT	
'801'
SERVER_PROTOCOL	
'HTTP/1.1'
UWSGI_APPID	
'mail.test.com|'
UWSGI_SCRIPT	
'instance.wsgi:application'
uwsgi.node	
b'modolast'
uwsgi.version	
b'2.0.21-debian'
wsgi.errors	
<_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>
wsgi.file_wrapper	
<built-in function uwsgi_sendfile>
wsgi.input	
<uwsgi._Input object at 0x7f2b35711930>
wsgi.multiprocess	
True
wsgi.multithread	
False
wsgi.run_once	
False
wsgi.url_scheme	
'https'
wsgi.version	
(1, 0)
Settings
Using settings module instance.settings
Setting	Value
ABSOLUTE_URL_OVERRIDES	
{}
ADMINS	
[]
ALLOWED_HOSTS	
['mail.test.com']
AMAVIS_DEFAULT_DATABASE_ENCODING	
'LATIN1'
APPEND_SLASH	
True
AUTHENTICATION_BACKENDS	
'********************'
AUTH_PASSWORD_VALIDATORS	
'********************'
AUTH_USER_MODEL	
'********************'
BASE_DIR	
'/srv/modoboa/instance'
CACHES	
{'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache',
             'LOCATION': 'redis://localhost:6379/0'}}
CACHE_MIDDLEWARE_ALIAS	
'default'
CACHE_MIDDLEWARE_KEY_PREFIX	
'********************'
CACHE_MIDDLEWARE_SECONDS	
600
CSRF_COOKIE_AGE	
31449600
CSRF_COOKIE_DOMAIN	
None
CSRF_COOKIE_HTTPONLY	
False
CSRF_COOKIE_NAME	
'csrftoken'
CSRF_COOKIE_PATH	
'/'
CSRF_COOKIE_SAMESITE	
'Lax'
CSRF_COOKIE_SECURE	
True
CSRF_FAILURE_VIEW	
'django.views.csrf.csrf_failure'
CSRF_HEADER_NAME	
'HTTP_X_CSRFTOKEN'
CSRF_TRUSTED_ORIGINS	
[]
CSRF_USE_SESSIONS	
False
DATABASES	
{'amavis': {'ATOMIC_REQUESTS': True,
            'AUTOCOMMIT': True,
            'CONN_HEALTH_CHECKS': False,
            'CONN_MAX_AGE': 0,
            'ENGINE': 'django.db.backends.postgresql',
            'HOST': '127.0.0.1',
            'NAME': 'amavis',
            'OPTIONS': {},
            'PASSWORD': '********************',
            'PORT': '5432',
            'TEST': {'CHARSET': None,
                     'COLLATION': None,
                     'MIGRATE': True,
                     'MIRROR': None,
                     'NAME': None},
            'TIME_ZONE': None,
            'USER': 'amavis'},
 'default': {'ATOMIC_REQUESTS': True,
             'AUTOCOMMIT': True,
             'CONN_HEALTH_CHECKS': False,
             'CONN_MAX_AGE': 0,
             'ENGINE': 'django.db.backends.postgresql',
             'HOST': '127.0.0.1',
             'NAME': 'modoboa',
             'OPTIONS': {},
             'PASSWORD': '********************',
             'PORT': '5432',
             'TEST': {'CHARSET': None,
                      'COLLATION': None,
                      'MIGRATE': True,
                      'MIRROR': None,
                      'NAME': None},
             'TIME_ZONE': None,
             'USER': 'modoboa'}}
DATABASE_ROUTERS	
['modoboa.amavis.dbrouter.AmavisRouter']
DATA_UPLOAD_MAX_MEMORY_SIZE	
2621440
DATA_UPLOAD_MAX_NUMBER_FIELDS	
1000
DATA_UPLOAD_MAX_NUMBER_FILES	
100
DATETIME_FORMAT	
'N j, Y, P'
DATETIME_INPUT_FORMATS	
['%Y-%m-%d %H:%M:%S',
 '%Y-%m-%d %H:%M:%S.%f',
 '%Y-%m-%d %H:%M',
 '%m/%d/%Y %H:%M:%S',
 '%m/%d/%Y %H:%M:%S.%f',
 '%m/%d/%Y %H:%M',
 '%m/%d/%y %H:%M:%S',
 '%m/%d/%y %H:%M:%S.%f',
 '%m/%d/%y %H:%M']
DATE_FORMAT	
'N j, Y'
DATE_INPUT_FORMATS	
['%Y-%m-%d',
 '%m/%d/%Y',
 '%m/%d/%y',
 '%b %d %Y',
 '%b %d, %Y',
 '%d %b %Y',
 '%d %b, %Y',
 '%B %d %Y',
 '%B %d, %Y',
 '%d %B %Y',
 '%d %B, %Y']
DEBUG	
True
DEBUG_PROPAGATE_EXCEPTIONS	
False
DECIMAL_SEPARATOR	
'.'
DEFAULT_AUTO_FIELD	
'django.db.models.AutoField'
DEFAULT_CHARSET	
'utf-8'
DEFAULT_EXCEPTION_REPORTER	
'django.views.debug.ExceptionReporter'
DEFAULT_EXCEPTION_REPORTER_FILTER	
'django.views.debug.SafeExceptionReporterFilter'
DEFAULT_FROM_EMAIL	
'webmaster@localhost'
DEFAULT_INDEX_TABLESPACE	
''
DEFAULT_TABLESPACE	
''
DISABLE_DASHBOARD_EXTERNAL_QUERIES	
False
DISALLOWED_USER_AGENTS	
[]
EMAIL_BACKEND	
'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST	
'localhost'
EMAIL_HOST_PASSWORD	
'********************'
EMAIL_HOST_USER	
''
EMAIL_PORT	
25
EMAIL_SSL_CERTFILE	
None
EMAIL_SSL_KEYFILE	
'********************'
EMAIL_SUBJECT_PREFIX	
'[Django] '
EMAIL_TIMEOUT	
None
EMAIL_USE_LOCALTIME	
False
EMAIL_USE_SSL	
False
EMAIL_USE_TLS	
False
FILE_UPLOAD_DIRECTORY_PERMISSIONS	
None
FILE_UPLOAD_HANDLERS	
['django.core.files.uploadhandler.MemoryFileUploadHandler',
 'django.core.files.uploadhandler.TemporaryFileUploadHandler']
FILE_UPLOAD_MAX_MEMORY_SIZE	
2621440
FILE_UPLOAD_PERMISSIONS	
420
FILE_UPLOAD_TEMP_DIR	
None
FIRST_DAY_OF_WEEK	
0
FIXTURE_DIRS	
[]
FORCE_SCRIPT_NAME	
None
FORMAT_MODULE_PATH	
None
FORMS_URLFIELD_ASSUME_HTTPS	
False
FORM_RENDERER	
'django.forms.renderers.DjangoTemplates'
IGNORABLE_404_URLS	
[]
INSTALLED_APPS	
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.sites',
 'django.contrib.staticfiles',
 'reversion',
 'oauth2_provider',
 'corsheaders',
 'rest_framework',
 'rest_framework.authtoken',
 'drf_spectacular',
 'phonenumber_field',
 'django_otp',
 'django_otp.plugins.otp_totp',
 'django_otp.plugins.otp_static',
 'django_rename_app',
 'django_rq',
 'modoboa',
 'modoboa.core',
 'modoboa.lib',
 'modoboa.admin',
 'modoboa.transport',
 'modoboa.relaydomains',
 'modoboa.limits',
 'modoboa.parameters',
 'modoboa.dnstools',
 'modoboa.policyd',
 'modoboa.maillog',
 'modoboa.pdfcredentials',
 'modoboa.dmarc',
 'modoboa.imap_migration',
 'modoboa.autoreply',
 'modoboa.sievefilters',
 'modoboa.contacts',
 'modoboa.calendars',
 'modoboa.webmail',
 'modoboa.amavis')
INTERNAL_IPS	
[]
LANGUAGES	
[('af', 'Afrikaans'),
 ('ar', 'Arabic'),
 ('ar-dz', 'Algerian Arabic'),
 ('ast', 'Asturian'),
 ('az', 'Azerbaijani'),
 ('bg', 'Bulgarian'),
 ('be', 'Belarusian'),
 ('bn', 'Bengali'),
 ('br', 'Breton'),
 ('bs', 'Bosnian'),
 ('ca', 'Catalan'),
 ('ckb', 'Central Kurdish (Sorani)'),
 ('cs', 'Czech'),
 ('cy', 'Welsh'),
 ('da', 'Danish'),
 ('de', 'German'),
 ('dsb', 'Lower Sorbian'),
 ('el', 'Greek'),
 ('en', 'English'),
 ('en-au', 'Australian English'),
 ('en-gb', 'British English'),
 ('eo', 'Esperanto'),
 ('es', 'Spanish'),
 ('es-ar', 'Argentinian Spanish'),
 ('es-co', 'Colombian Spanish'),
 ('es-mx', 'Mexican Spanish'),
 ('es-ni', 'Nicaraguan Spanish'),
 ('es-ve', 'Venezuelan Spanish'),
 ('et', 'Estonian'),
 ('eu', 'Basque'),
 ('fa', 'Persian'),
 ('fi', 'Finnish'),
 ('fr', 'French'),
 ('fy', 'Frisian'),
 ('ga', 'Irish'),
 ('gd', 'Scottish Gaelic'),
 ('gl', 'Galician'),
 ('he', 'Hebrew'),
 ('hi', 'Hindi'),
 ('hr', 'Croatian'),
 ('hsb', 'Upper Sorbian'),
 ('hu', 'Hungarian'),
 ('hy', 'Armenian'),
 ('ia', 'Interlingua'),
 ('id', 'Indonesian'),
 ('ig', 'Igbo'),
 ('io', 'Ido'),
 ('is', 'Icelandic'),
 ('it', 'Italian'),
 ('ja', 'Japanese'),
 ('ka', 'Georgian'),
 ('kab', 'Kabyle'),
 ('kk', 'Kazakh'),
 ('km', 'Khmer'),
 ('kn', 'Kannada'),
 ('ko', 'Korean'),
 ('ky', 'Kyrgyz'),
 ('lb', 'Luxembourgish'),
 ('lt', 'Lithuanian'),
 ('lv', 'Latvian'),
 ('mk', 'Macedonian'),
 ('ml', 'Malayalam'),
 ('mn', 'Mongolian'),
 ('mr', 'Marathi'),
 ('ms', 'Malay'),
 ('my', 'Burmese'),
 ('nb', 'Norwegian Bokmål'),
 ('ne', 'Nepali'),
 ('nl', 'Dutch'),
 ('nn', 'Norwegian Nynorsk'),
 ('os', 'Ossetic'),
 ('pa', 'Punjabi'),
 ('pl', 'Polish'),
 ('pt', 'Portuguese'),
 ('pt-br', 'Brazilian Portuguese'),
 ('ro', 'Romanian'),
 ('ru', 'Russian'),
 ('sk', 'Slovak'),
 ('sl', 'Slovenian'),
 ('sq', 'Albanian'),
 ('sr', 'Serbian'),
 ('sr-latn', 'Serbian Latin'),
 ('sv', 'Swedish'),
 ('sw', 'Swahili'),
 ('ta', 'Tamil'),
 ('te', 'Telugu'),
 ('tg', 'Tajik'),
 ('th', 'Thai'),
 ('tk', 'Turkmen'),
 ('tr', 'Turkish'),
 ('tt', 'Tatar'),
 ('udm', 'Udmurt'),
 ('ug', 'Uyghur'),
 ('uk', 'Ukrainian'),
 ('ur', 'Urdu'),
 ('uz', 'Uzbek'),
 ('vi', 'Vietnamese'),
 ('zh-hans', 'Simplified Chinese'),
 ('zh-hant', 'Traditional Chinese')]
LANGUAGES_BIDI	
['he', 'ar', 'ar-dz', 'ckb', 'fa', 'ug', 'ur']
LANGUAGE_CODE	
'en'
LANGUAGE_COOKIE_AGE	
None
LANGUAGE_COOKIE_DOMAIN	
None
LANGUAGE_COOKIE_HTTPONLY	
False
LANGUAGE_COOKIE_NAME	
'django_language'
LANGUAGE_COOKIE_PATH	
'/'
LANGUAGE_COOKIE_SAMESITE	
None
LANGUAGE_COOKIE_SECURE	
False
LOCALE_PATHS	
[]
LOGGING	
{'formatters': {'syslog': {'format': '%(name)s: %(levelname)s %(message)s'}},
 'handlers': {'mail-admins': {'class': 'django.utils.log.AdminEmailHandler',
                              'include_html': True,
                              'level': 'ERROR'},
              'modoboa': {'class': 'modoboa.core.loggers.SQLHandler'},
              'syslog-auth': '********************',
              'syslog-mail': {'class': 'logging.handlers.SysLogHandler',
                              'facility': 2,
                              'formatter': 'syslog'}},
 'loggers': {'django': {'handlers': ['mail-admins'],
                        'level': 'ERROR',
                        'propagate': False},
             'modoboa.admin': {'handlers': ['modoboa'],
                               'level': 'INFO',
                               'propagate': False},
             'modoboa.auth': '********************',
             'modoboa.policyd': {'handlers': ['syslog-mail'],
                                 'level': 'INFO',
                                 'propagate': False}},
 'version': 1}
LOGGING_CONFIG	
'logging.config.dictConfig'
LOGIN_REDIRECT_URL	
'/accounts/profile/'
LOGIN_URL	
'/accounts/login/'
LOGOUT_REDIRECT_URL	
None
MANAGERS	
[]
MEDIA_ROOT	
'/srv/modoboa/instance/media'
MEDIA_URL	
'/media/'
MESSAGE_STORAGE	
'django.contrib.messages.storage.fallback.FallbackStorage'
MIDDLEWARE	
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'x_forwarded_for.middleware.XForwardedForMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'modoboa.core.middleware.LocalConfigMiddleware',
 'modoboa.lib.middleware.CommonExceptionCatcher',
 'modoboa.lib.middleware.RequestCatcherMiddleware')
MIGRATION_MODULES	
{}
MODOBOA_API_URL	
'********************'
MODOBOA_APPS	
('modoboa',
 'modoboa.core',
 'modoboa.lib',
 'modoboa.admin',
 'modoboa.transport',
 'modoboa.relaydomains',
 'modoboa.limits',
 'modoboa.parameters',
 'modoboa.dnstools',
 'modoboa.policyd',
 'modoboa.maillog',
 'modoboa.pdfcredentials',
 'modoboa.dmarc',
 'modoboa.imap_migration',
 'modoboa.autoreply',
 'modoboa.sievefilters',
 'modoboa.contacts',
 'modoboa.calendars',
 'modoboa.webmail',
 'modoboa.amavis')
MONTH_DAY_FORMAT	
'F j'
NUMBER_GROUPING	
0
OAUTH2_PROVIDER	
'********************'
OTP_TOTP_ISSUER	
'mail.test.com'
PASSWORD_HASHERS	
'********************'
PASSWORD_RESET_TIMEOUT	
'********************'
PHONENUMBER_DB_FORMAT	
'INTERNATIONAL'
PID_FILE_STORAGE_PATH	
'/var/run'
PREPEND_WWW	
False
REDIS_HOST	
'localhost'
REDIS_PORT	
6379
REDIS_QUOTA_DB	
0
REDIS_URL	
'redis://localhost:6379/0'
REST_FRAMEWORK	
{'DEFAULT_AUTHENTICATION_CLASSES': '********************',
 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
 'DEFAULT_THROTTLE_RATES': {'ddos': '5/second',
                            'ddos_lesser': '200/minute',
                            'login': '10/minute',
                            'password_recovery_apply': '********************',
                            'password_recovery_request': '********************',
                            'password_recovery_totp_check': '********************',
                            'user': '300/minute'},
 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning'}
ROOT_URLCONF	
'instance.urls'
RQ_QUEUES	
{'dkim': {'DB': 0,
          'HOST': 'localhost',
          'PORT': 6379,
          'URL': 'redis://localhost:6379/0'},
 'modoboa': {'DB': 0,
             'HOST': 'localhost',
             'PORT': 6379,
             'URL': 'redis://localhost:6379/0'}}
SECRET_KEY	
'********************'
SECRET_KEY_FALLBACKS	
'********************'
SECURE_CONTENT_TYPE_NOSNIFF	
True
SECURE_CROSS_ORIGIN_OPENER_POLICY	
'same-origin'
SECURE_HSTS_INCLUDE_SUBDOMAINS	
False
SECURE_HSTS_PRELOAD	
False
SECURE_HSTS_SECONDS	
0
SECURE_PROXY_SSL_HEADER	
None
SECURE_REDIRECT_EXEMPT	
[]
SECURE_REFERRER_POLICY	
'same-origin'
SECURE_SSL_HOST	
None
SECURE_SSL_REDIRECT	
False
SERVER_EMAIL	
'root@localhost'
SESSION_CACHE_ALIAS	
'default'
SESSION_COOKIE_AGE	
1209600
SESSION_COOKIE_DOMAIN	
None
SESSION_COOKIE_HTTPONLY	
True
SESSION_COOKIE_NAME	
'sessionid'
SESSION_COOKIE_PATH	
'/'
SESSION_COOKIE_SAMESITE	
'Lax'
SESSION_COOKIE_SECURE	
True
SESSION_ENGINE	
'django.contrib.sessions.backends.db'
SESSION_EXPIRE_AT_BROWSER_CLOSE	
False
SESSION_FILE_PATH	
None
SESSION_SAVE_EVERY_REQUEST	
False
SESSION_SERIALIZER	
'django.contrib.sessions.serializers.JSONSerializer'
SETTINGS_MODULE	
'instance.settings'
SHORT_DATETIME_FORMAT	
'm/d/Y P'
SHORT_DATE_FORMAT	
'm/d/Y'
SIGNING_BACKEND	
'django.core.signing.TimestampSigner'
SILENCED_SYSTEM_CHECKS	
['security.W019']
SITE_ID	
1
SPECTACULAR_SETTINGS	
{'SCHEMA_PATH_PREFIX': '/api/v[0-9]',
 'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'],
 'TITLE': 'Modoboa API',
 'VERSION': None}
STATICFILES_DIRS	
[]
STATICFILES_FINDERS	
['django.contrib.staticfiles.finders.FileSystemFinder',
 'django.contrib.staticfiles.finders.AppDirectoriesFinder']
STATIC_ROOT	
'/srv/modoboa/instance/sitestatic'
STATIC_URL	
'/sitestatic/'
STORAGES	
{'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'},
 'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'}}
TEMPLATES	
[{'APP_DIRS': True,
  'BACKEND': 'django.template.backends.django.DjangoTemplates',
  'DIRS': [],
  'OPTIONS': {'context_processors': ['django.template.context_processors.debug',
                                     'django.template.context_processors.request',
                                     'django.contrib.auth.context_processors.auth',
                                     'django.template.context_processors.i18n',
                                     'django.template.context_processors.media',
                                     'django.template.context_processors.static',
                                     'django.template.context_processors.tz',
                                     'django.contrib.messages.context_processors.messages'],
              'debug': False}}]
TEST_NON_SERIALIZED_APPS	
[]
TEST_RUNNER	
'django.test.runner.DiscoverRunner'
THOUSAND_SEPARATOR	
','
TIME_FORMAT	
'P'
TIME_INPUT_FORMATS	
['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
TIME_ZONE	
'Asia/Tehran'
USE_I18N	
True
USE_L10N	
True
USE_THOUSAND_SEPARATOR	
False
USE_TZ	
True
USE_X_FORWARDED_HOST	
False
USE_X_FORWARDED_PORT	
False
WSGI_APPLICATION	
'instance.wsgi.application'
X_FRAME_OPTIONS	
'SAMEORIGIN'
YEAR_MONTH_FORMAT	
'F Y'
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard page generated by the handler for this status code.
<!-- gh-comment-id:3291538082 --> @nadihighlander commented on GitHub (Sep 15, 2025): PutError at /api/v2/user-calendars/3/events/ PutError at '409 Conflict Conflict in the request.', reason no reason Request Method: POST Request URL: https://mail.test.com/api/v2/user-calendars/3/events/ Django Version: 5.2.6 Exception Type: PutError Exception Value: PutError at '409 Conflict Conflict in the request.', reason no reason Exception Location: /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 772, in _put Raised during: modoboa.calendars.viewsets.UserEventViewSet Python Executable: /usr/bin/uwsgi-core Python Version: 3.11.2 Python Path: ['.', '', '/usr/lib/python311.zip', '/usr/lib/python3.11', '/usr/lib/python3.11/lib-dynload', '/srv/modoboa/env/lib/python3.11/site-packages'] Server time: Mon, 15 Sep 2025 14:10:57 +0330 Traceback Switch to copy-and-paste view /srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/exception.py, line 55, in inner return inner else: @wraps(get_response) def inner(request): try: response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ … except Exception as exc: response = response_for_exception(request, exc) return response return inner Local vars /srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/base.py, line 197, in _get_response if response is None: wrapped_callback = self.make_view_atomic(callback) # If it is an asynchronous view, run it in a subthread. if iscoroutinefunction(wrapped_callback): wrapped_callback = async_to_sync(wrapped_callback) try: response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … except Exception as e: response = self.process_exception_by_middleware(e, request) if response is None: raise # Complain if the view returned None (a common error). Local vars /usr/lib/python3.11/contextlib.py, line 81, in inner """ return self def __call__(self, func): @wraps(func) def inner(*args, **kwds): with self._recreate_cm(): return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ … return inner class AsyncContextDecorator(object): "A base class or mixin that enables async context managers to work as decorators." Local vars /usr/lib/python3.11/contextlib.py, line 81, in inner """ return self def __call__(self, func): @wraps(func) def inner(*args, **kwds): with self._recreate_cm(): return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ … return inner class AsyncContextDecorator(object): "A base class or mixin that enables async context managers to work as decorators." Local vars /srv/modoboa/env/lib/python3.11/site-packages/django/views/decorators/csrf.py, line 65, in _view_wrapper async def _view_wrapper(request, *args, **kwargs): return await view_func(request, *args, **kwargs) else: def _view_wrapper(request, *args, **kwargs): return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … _view_wrapper.csrf_exempt = True return wraps(view_func)(_view_wrapper) Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/viewsets.py, line 125, in view setattr(self, method, handler) self.request = request self.args = args self.kwargs = kwargs # And continue as usual return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 515, in dispatch self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^ … self.response = self.finalize_response(request, response, *args, **kwargs) return self.response def options(self, request, *args, **kwargs): """ Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 475, in handle_exception exception_handler = self.get_exception_handler() context = self.get_exception_handler_context() response = exception_handler(exc, context) if response is None: self.raise_uncaught_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … response.exception = True return response def raise_uncaught_exception(self, exc): if settings.DEBUG: Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 486, in raise_uncaught_exception def raise_uncaught_exception(self, exc): if settings.DEBUG: request = self.request renderer_format = getattr(request.accepted_renderer, 'format') use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin') request.force_plaintext_errors(use_plaintext_traceback) raise exc ^^^^^^^^^ … # Note: Views are made CSRF exempt from within `as_view` as to prevent # accidental removal of this exemption in cases where `dispatch` needs to # be overridden. def dispatch(self, request, *args, **kwargs): """ Local vars /srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py, line 512, in dispatch # Get the appropriate handler method if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … except Exception as exc: response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response Local vars /srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/viewsets.py, line 121, in create """ """Create new event.""" serializer = self.get_serializer() serializer.is_valid(raise_exception=True) backend = backends.get_backend_from_request( "caldav_", request, serializer.validated_data["calendar"] ) uid = backend.create_event(serializer.validated_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … event = dict(serializer.validated_data) calendar = serializer.validated_data["calendar"] event["id"] = uid event["color"] = calendar.color event["calendar"] = {"pk": calendar.pk} if self.type == "shared": Local vars /srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/backends/caldav_.py, line 91, in create_event cal.vevent.add("summary").value = data["title"] if not data["allDay"]: cal.vevent.add("dtstart").value = data["start"] cal.vevent.add("dtend").value = data["end"] else: cal.vevent.add("dtstart").value = data["start"].date() cal.vevent.add("dtend").value = data["end"].date() self.remote_cal.add_event(cal) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … return uid def update_event(self, uid, original_data): """Update an existing event.""" data = dict(original_data) url = f"{self.remote_cal.url.geturl()}/{uid}.ics" Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py, line 553, in save_event return o ## TODO: maybe we should deprecate those three def save_event(self, *largs, **kwargs) -> "Event": """ Returns ``self.save_object(Event, ...)`` - see :class:`save_object` """ return self.save_object(Event, *largs, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … def save_todo(self, *largs, **kwargs) -> "Todo": """ Returns ``self.save_object(Todo, ...)`` - so see :class:`save_object` """ return self.save_object(Todo, *largs, **kwargs) Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py, line 540, in save_object o = objclass( self.client, data=self._use_or_create_ics( ical, objtype=f"V{objclass.__name__.upper()}", **ical_data ), parent=self, ) o = o.save(no_overwrite=no_overwrite, no_create=no_create) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … ## TODO: Saving nothing is currently giving an object with None as URL. ## This should probably be changed in some future version to raise an error ## See also CalendarObjectResource.save() if o.url is not None: o._handle_reverse_relations(fix=True) return o Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 1000, in save return obj.save(increase_seqno=increase_seqno) if "SEQUENCE" in self.icalendar_component: seqno = self.icalendar_component.pop("SEQUENCE", None) if seqno is not None: self.icalendar_component.add("SEQUENCE", seqno + 1) self._create(id=self.id, path=path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … return self def is_loaded(self): """Returns True if there exists data in the object. An object is considered not to be loaded if it contains no data but just the URL. Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 777, in _create return self._put(False) else: raise error.PutError(errmsg(r)) def _create(self, id=None, path=None, retry_on_failure=True) -> None: ## TODO: Find a better method name self._find_id_path(id=id, path=path) self._put() ^^^^^^^^^^^ … def _generate_url(self): ## See https://github.com/python-caldav/caldav/issues/143 for the rationale behind double-quoting slashes ## TODO: should try to wrap my head around issues that arises when id contains weird characters. maybe it's ## better to generate a new uuid here, particularly if id is in some unexpected format. if not self.id: Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 770, in _put import vobject except ImportError: retry_on_failure = False if retry_on_failure: ## This looks like a noop, but the object may be "cleaned". ## See https://github.com/python-caldav/caldav/issues/43 self.vobject_instance return self._put(False) ^^^^^^^^^^^^^^^^ … else: raise error.PutError(errmsg(r)) def _create(self, id=None, path=None, retry_on_failure=True) -> None: ## TODO: Find a better method name self._find_id_path(id=id, path=path) Local vars /srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py, line 772, in _put retry_on_failure = False if retry_on_failure: ## This looks like a noop, but the object may be "cleaned". ## See https://github.com/python-caldav/caldav/issues/43 self.vobject_instance return self._put(False) else: raise error.PutError(errmsg(r)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ … def _create(self, id=None, path=None, retry_on_failure=True) -> None: ## TODO: Find a better method name self._find_id_path(id=id, path=path) self._put() Local vars Environment: Request Method: POST Request URL: https://mail.test.com/api/v2/user-calendars/3/events/ Django Version: 5.2.6 Python Version: 3.11.2 Installed Applications: ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.sites', 'django.contrib.staticfiles', 'reversion', 'oauth2_provider', 'corsheaders', 'rest_framework', 'rest_framework.authtoken', 'drf_spectacular', 'phonenumber_field', 'django_otp', 'django_otp.plugins.otp_totp', 'django_otp.plugins.otp_static', 'django_rename_app', 'django_rq', 'modoboa', 'modoboa.core', 'modoboa.lib', 'modoboa.admin', 'modoboa.transport', 'modoboa.relaydomains', 'modoboa.limits', 'modoboa.parameters', 'modoboa.dnstools', 'modoboa.policyd', 'modoboa.maillog', 'modoboa.pdfcredentials', 'modoboa.dmarc', 'modoboa.imap_migration', 'modoboa.autoreply', 'modoboa.sievefilters', 'modoboa.contacts', 'modoboa.calendars', 'modoboa.webmail', 'modoboa.amavis') Installed Middleware: ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'x_forwarded_for.middleware.XForwardedForMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'modoboa.core.middleware.LocalConfigMiddleware', 'modoboa.lib.middleware.CommonExceptionCatcher', 'modoboa.lib.middleware.RequestCatcherMiddleware') Traceback (most recent call last): File "/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/contextlib.py", line 81, in inner return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/contextlib.py", line 81, in inner return func(*args, **kwds) ^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/viewsets.py", line 125, in view return self.dispatch(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 515, in dispatch response = self.handle_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 475, in handle_exception self.raise_uncaught_exception(exc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception raise exc ^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/rest_framework/views.py", line 512, in dispatch response = handler(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/viewsets.py", line 121, in create uid = backend.create_event(serializer.validated_data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/modoboa/calendars/backends/caldav_.py", line 91, in create_event self.remote_cal.add_event(cal) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py", line 553, in save_event return self.save_object(Event, *largs, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/collection.py", line 540, in save_object o = o.save(no_overwrite=no_overwrite, no_create=no_create) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 1000, in save self._create(id=self.id, path=path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 777, in _create self._put() ^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 770, in _put return self._put(False) ^^^^^^^^^^^^^^^^ File "/srv/modoboa/env/lib/python3.11/site-packages/caldav/calendarobjectresource.py", line 772, in _put raise error.PutError(errmsg(r)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Exception Type: PutError at /api/v2/user-calendars/3/events/ Exception Value: PutError at '409 Conflict Conflict in the request.', reason no reason Request information USER user1@test.com GET No GET data POST No POST data FILES No FILES data COOKIES Variable Value SERVERID 'cookie1' django_language 'en' csrftoken '********************' sessionid '********************' META Variable Value CONTENT_LENGTH '99' CONTENT_TYPE 'application/json' CSRF_COOKIE 'deCK5OirJMkzeftzssFakEvbw2v58eOW' DOCUMENT_ROOT '/srv/modoboa/instance' HTTP_ACCEPT 'application/json, text/plain, */*' HTTP_ACCEPT_ENCODING 'gzip, deflate, br, zstd' HTTP_ACCEPT_LANGUAGE 'en' HTTP_AUTHORIZATION '********************' HTTP_CONTENT_LENGTH '99' HTTP_CONTENT_TYPE 'application/json' HTTP_COOKIE '********************' HTTP_DNT '1' HTTP_HOST 'mail.test.com' HTTP_ORIGIN 'https://mail.test.com' HTTP_REFERER 'https://mail.test.com/user/calendars' HTTP_SEC_CH_UA '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"' HTTP_SEC_CH_UA_MOBILE '?0' HTTP_SEC_CH_UA_PLATFORM '"Windows"' HTTP_SEC_FETCH_DEST 'empty' HTTP_SEC_FETCH_MODE 'cors' HTTP_SEC_FETCH_SITE 'same-origin' HTTP_USER_AGENT ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like ' 'Gecko) Chrome/140.0.0.0 Safari/537.36') HTTP_X_FORWARDED_FOR '5.239.172.182' HTTP_X_FORWARDED_PORT '443' HTTP_X_FORWARDED_PROTO 'https' PATH_INFO '/api/v2/user-calendars/3/events/' QUERY_STRING '' REMOTE_ADDR '5.239.172.182' REMOTE_PORT '45062' REQUEST_METHOD 'POST' REQUEST_SCHEME 'http' REQUEST_URI '/api/v2/user-calendars/3/events/' SCRIPT_NAME '' SERVER_NAME 'mail.test.com' SERVER_PORT '801' SERVER_PROTOCOL 'HTTP/1.1' UWSGI_APPID 'mail.test.com|' UWSGI_SCRIPT 'instance.wsgi:application' uwsgi.node b'modolast' uwsgi.version b'2.0.21-debian' wsgi.errors <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'> wsgi.file_wrapper <built-in function uwsgi_sendfile> wsgi.input <uwsgi._Input object at 0x7f2b35711930> wsgi.multiprocess True wsgi.multithread False wsgi.run_once False wsgi.url_scheme 'https' wsgi.version (1, 0) Settings Using settings module instance.settings Setting Value ABSOLUTE_URL_OVERRIDES {} ADMINS [] ALLOWED_HOSTS ['mail.test.com'] AMAVIS_DEFAULT_DATABASE_ENCODING 'LATIN1' APPEND_SLASH True AUTHENTICATION_BACKENDS '********************' AUTH_PASSWORD_VALIDATORS '********************' AUTH_USER_MODEL '********************' BASE_DIR '/srv/modoboa/instance' CACHES {'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://localhost:6379/0'}} CACHE_MIDDLEWARE_ALIAS 'default' CACHE_MIDDLEWARE_KEY_PREFIX '********************' CACHE_MIDDLEWARE_SECONDS 600 CSRF_COOKIE_AGE 31449600 CSRF_COOKIE_DOMAIN None CSRF_COOKIE_HTTPONLY False CSRF_COOKIE_NAME 'csrftoken' CSRF_COOKIE_PATH '/' CSRF_COOKIE_SAMESITE 'Lax' CSRF_COOKIE_SECURE True CSRF_FAILURE_VIEW 'django.views.csrf.csrf_failure' CSRF_HEADER_NAME 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS [] CSRF_USE_SESSIONS False DATABASES {'amavis': {'ATOMIC_REQUESTS': True, 'AUTOCOMMIT': True, 'CONN_HEALTH_CHECKS': False, 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.postgresql', 'HOST': '127.0.0.1', 'NAME': 'amavis', 'OPTIONS': {}, 'PASSWORD': '********************', 'PORT': '5432', 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None}, 'TIME_ZONE': None, 'USER': 'amavis'}, 'default': {'ATOMIC_REQUESTS': True, 'AUTOCOMMIT': True, 'CONN_HEALTH_CHECKS': False, 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.postgresql', 'HOST': '127.0.0.1', 'NAME': 'modoboa', 'OPTIONS': {}, 'PASSWORD': '********************', 'PORT': '5432', 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None}, 'TIME_ZONE': None, 'USER': 'modoboa'}} DATABASE_ROUTERS ['modoboa.amavis.dbrouter.AmavisRouter'] DATA_UPLOAD_MAX_MEMORY_SIZE 2621440 DATA_UPLOAD_MAX_NUMBER_FIELDS 1000 DATA_UPLOAD_MAX_NUMBER_FILES 100 DATETIME_FORMAT 'N j, Y, P' DATETIME_INPUT_FORMATS ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M'] DATE_FORMAT 'N j, Y' DATE_INPUT_FORMATS ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y'] DEBUG True DEBUG_PROPAGATE_EXCEPTIONS False DECIMAL_SEPARATOR '.' DEFAULT_AUTO_FIELD 'django.db.models.AutoField' DEFAULT_CHARSET 'utf-8' DEFAULT_EXCEPTION_REPORTER 'django.views.debug.ExceptionReporter' DEFAULT_EXCEPTION_REPORTER_FILTER 'django.views.debug.SafeExceptionReporterFilter' DEFAULT_FROM_EMAIL 'webmaster@localhost' DEFAULT_INDEX_TABLESPACE '' DEFAULT_TABLESPACE '' DISABLE_DASHBOARD_EXTERNAL_QUERIES False DISALLOWED_USER_AGENTS [] EMAIL_BACKEND 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST 'localhost' EMAIL_HOST_PASSWORD '********************' EMAIL_HOST_USER '' EMAIL_PORT 25 EMAIL_SSL_CERTFILE None EMAIL_SSL_KEYFILE '********************' EMAIL_SUBJECT_PREFIX '[Django] ' EMAIL_TIMEOUT None EMAIL_USE_LOCALTIME False EMAIL_USE_SSL False EMAIL_USE_TLS False FILE_UPLOAD_DIRECTORY_PERMISSIONS None FILE_UPLOAD_HANDLERS ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler'] FILE_UPLOAD_MAX_MEMORY_SIZE 2621440 FILE_UPLOAD_PERMISSIONS 420 FILE_UPLOAD_TEMP_DIR None FIRST_DAY_OF_WEEK 0 FIXTURE_DIRS [] FORCE_SCRIPT_NAME None FORMAT_MODULE_PATH None FORMS_URLFIELD_ASSUME_HTTPS False FORM_RENDERER 'django.forms.renderers.DjangoTemplates' IGNORABLE_404_URLS [] INSTALLED_APPS ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.sites', 'django.contrib.staticfiles', 'reversion', 'oauth2_provider', 'corsheaders', 'rest_framework', 'rest_framework.authtoken', 'drf_spectacular', 'phonenumber_field', 'django_otp', 'django_otp.plugins.otp_totp', 'django_otp.plugins.otp_static', 'django_rename_app', 'django_rq', 'modoboa', 'modoboa.core', 'modoboa.lib', 'modoboa.admin', 'modoboa.transport', 'modoboa.relaydomains', 'modoboa.limits', 'modoboa.parameters', 'modoboa.dnstools', 'modoboa.policyd', 'modoboa.maillog', 'modoboa.pdfcredentials', 'modoboa.dmarc', 'modoboa.imap_migration', 'modoboa.autoreply', 'modoboa.sievefilters', 'modoboa.contacts', 'modoboa.calendars', 'modoboa.webmail', 'modoboa.amavis') INTERNAL_IPS [] LANGUAGES [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ar-dz', 'Algerian Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('ckb', 'Central Kurdish (Sorani)'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('ig', 'Igbo'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('ky', 'Kyrgyz'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('ms', 'Malay'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('tg', 'Tajik'), ('th', 'Thai'), ('tk', 'Turkmen'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('ug', 'Uyghur'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('uz', 'Uzbek'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')] LANGUAGES_BIDI ['he', 'ar', 'ar-dz', 'ckb', 'fa', 'ug', 'ur'] LANGUAGE_CODE 'en' LANGUAGE_COOKIE_AGE None LANGUAGE_COOKIE_DOMAIN None LANGUAGE_COOKIE_HTTPONLY False LANGUAGE_COOKIE_NAME 'django_language' LANGUAGE_COOKIE_PATH '/' LANGUAGE_COOKIE_SAMESITE None LANGUAGE_COOKIE_SECURE False LOCALE_PATHS [] LOGGING {'formatters': {'syslog': {'format': '%(name)s: %(levelname)s %(message)s'}}, 'handlers': {'mail-admins': {'class': 'django.utils.log.AdminEmailHandler', 'include_html': True, 'level': 'ERROR'}, 'modoboa': {'class': 'modoboa.core.loggers.SQLHandler'}, 'syslog-auth': '********************', 'syslog-mail': {'class': 'logging.handlers.SysLogHandler', 'facility': 2, 'formatter': 'syslog'}}, 'loggers': {'django': {'handlers': ['mail-admins'], 'level': 'ERROR', 'propagate': False}, 'modoboa.admin': {'handlers': ['modoboa'], 'level': 'INFO', 'propagate': False}, 'modoboa.auth': '********************', 'modoboa.policyd': {'handlers': ['syslog-mail'], 'level': 'INFO', 'propagate': False}}, 'version': 1} LOGGING_CONFIG 'logging.config.dictConfig' LOGIN_REDIRECT_URL '/accounts/profile/' LOGIN_URL '/accounts/login/' LOGOUT_REDIRECT_URL None MANAGERS [] MEDIA_ROOT '/srv/modoboa/instance/media' MEDIA_URL '/media/' MESSAGE_STORAGE 'django.contrib.messages.storage.fallback.FallbackStorage' MIDDLEWARE ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'x_forwarded_for.middleware.XForwardedForMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'modoboa.core.middleware.LocalConfigMiddleware', 'modoboa.lib.middleware.CommonExceptionCatcher', 'modoboa.lib.middleware.RequestCatcherMiddleware') MIGRATION_MODULES {} MODOBOA_API_URL '********************' MODOBOA_APPS ('modoboa', 'modoboa.core', 'modoboa.lib', 'modoboa.admin', 'modoboa.transport', 'modoboa.relaydomains', 'modoboa.limits', 'modoboa.parameters', 'modoboa.dnstools', 'modoboa.policyd', 'modoboa.maillog', 'modoboa.pdfcredentials', 'modoboa.dmarc', 'modoboa.imap_migration', 'modoboa.autoreply', 'modoboa.sievefilters', 'modoboa.contacts', 'modoboa.calendars', 'modoboa.webmail', 'modoboa.amavis') MONTH_DAY_FORMAT 'F j' NUMBER_GROUPING 0 OAUTH2_PROVIDER '********************' OTP_TOTP_ISSUER 'mail.test.com' PASSWORD_HASHERS '********************' PASSWORD_RESET_TIMEOUT '********************' PHONENUMBER_DB_FORMAT 'INTERNATIONAL' PID_FILE_STORAGE_PATH '/var/run' PREPEND_WWW False REDIS_HOST 'localhost' REDIS_PORT 6379 REDIS_QUOTA_DB 0 REDIS_URL 'redis://localhost:6379/0' REST_FRAMEWORK {'DEFAULT_AUTHENTICATION_CLASSES': '********************', 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', 'DEFAULT_THROTTLE_RATES': {'ddos': '5/second', 'ddos_lesser': '200/minute', 'login': '10/minute', 'password_recovery_apply': '********************', 'password_recovery_request': '********************', 'password_recovery_totp_check': '********************', 'user': '300/minute'}, 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning'} ROOT_URLCONF 'instance.urls' RQ_QUEUES {'dkim': {'DB': 0, 'HOST': 'localhost', 'PORT': 6379, 'URL': 'redis://localhost:6379/0'}, 'modoboa': {'DB': 0, 'HOST': 'localhost', 'PORT': 6379, 'URL': 'redis://localhost:6379/0'}} SECRET_KEY '********************' SECRET_KEY_FALLBACKS '********************' SECURE_CONTENT_TYPE_NOSNIFF True SECURE_CROSS_ORIGIN_OPENER_POLICY 'same-origin' SECURE_HSTS_INCLUDE_SUBDOMAINS False SECURE_HSTS_PRELOAD False SECURE_HSTS_SECONDS 0 SECURE_PROXY_SSL_HEADER None SECURE_REDIRECT_EXEMPT [] SECURE_REFERRER_POLICY 'same-origin' SECURE_SSL_HOST None SECURE_SSL_REDIRECT False SERVER_EMAIL 'root@localhost' SESSION_CACHE_ALIAS 'default' SESSION_COOKIE_AGE 1209600 SESSION_COOKIE_DOMAIN None SESSION_COOKIE_HTTPONLY True SESSION_COOKIE_NAME 'sessionid' SESSION_COOKIE_PATH '/' SESSION_COOKIE_SAMESITE 'Lax' SESSION_COOKIE_SECURE True SESSION_ENGINE 'django.contrib.sessions.backends.db' SESSION_EXPIRE_AT_BROWSER_CLOSE False SESSION_FILE_PATH None SESSION_SAVE_EVERY_REQUEST False SESSION_SERIALIZER 'django.contrib.sessions.serializers.JSONSerializer' SETTINGS_MODULE 'instance.settings' SHORT_DATETIME_FORMAT 'm/d/Y P' SHORT_DATE_FORMAT 'm/d/Y' SIGNING_BACKEND 'django.core.signing.TimestampSigner' SILENCED_SYSTEM_CHECKS ['security.W019'] SITE_ID 1 SPECTACULAR_SETTINGS {'SCHEMA_PATH_PREFIX': '/api/v[0-9]', 'SERVE_PERMISSIONS': ['rest_framework.permissions.IsAuthenticated'], 'TITLE': 'Modoboa API', 'VERSION': None} STATICFILES_DIRS [] STATICFILES_FINDERS ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder'] STATIC_ROOT '/srv/modoboa/instance/sitestatic' STATIC_URL '/sitestatic/' STORAGES {'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'}, 'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'}} TEMPLATES [{'APP_DIRS': True, 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages'], 'debug': False}}] TEST_NON_SERIALIZED_APPS [] TEST_RUNNER 'django.test.runner.DiscoverRunner' THOUSAND_SEPARATOR ',' TIME_FORMAT 'P' TIME_INPUT_FORMATS ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] TIME_ZONE 'Asia/Tehran' USE_I18N True USE_L10N True USE_THOUSAND_SEPARATOR False USE_TZ True USE_X_FORWARDED_HOST False USE_X_FORWARDED_PORT False WSGI_APPLICATION 'instance.wsgi.application' X_FRAME_OPTIONS 'SAMEORIGIN' YEAR_MONTH_FORMAT 'F Y' You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard page generated by the handler for this status code.
Author
Owner

@tonioo commented on GitHub (Sep 17, 2025):

@nadihighlander Can you check Radicale logs to see what could be the problem? (/var/log/supervisor/radicale...)

<!-- gh-comment-id:3303430124 --> @tonioo commented on GitHub (Sep 17, 2025): @nadihighlander Can you check Radicale logs to see what could be the problem? (/var/log/supervisor/radicale...)
Author
Owner

@nadihighlander commented on GitHub (Sep 21, 2025):

I use haproxy for ssl endpoint and public ip
I installed modoboa 2.5.1 on another server using local ip (using haproxy as reverse proxy)
There are authorization errors in radicale log
...
REPORT request for '/user1@test.comr/self' with depth '1' received from ::1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1'
Access to '/user1@test.comr/self' denied for anonymous user
REPORT response status for '/user1@test.comr/self' with depth '1' in 0.001 seconds: 401 Unauthorized
REPORT request for '/user1@test.comr/jobs' with depth '1' received from 127.0.0.1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1'
Access to '/user1@test.comr/jobs' denied for anonymous user
REPORT response status for '/user1@test.comr/jobs' with depth '1' in 0.001 seconds: 401 Unauthorized
REPORT request for '/user1@test.comr/test1' with depth '1' received from ::1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1'
Access to '/user1@test.comr/test1' denied for anonymous user
REPORT response status for '/user1@test.comr/test1' with depth '1' in 0.002 seconds: 401 Unauthorized
REPORT request for '/user1@test.comr/self' with depth '1' received from 127.0.0.1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1'
REPORT request for '/user1@test.comr/jobs' with depth '1' received from ::1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1'
REPORT request for '/user1@test.comr/test1' with depth '1' received from 127.0.0.1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1'
Successful login: 'user1@test.comr' (radicale_modoboa_auth_oauth2)
REPORT response status for '/user1@test.comr/self' with depth '1' in 1.582 seconds: 207 Multi-Status
Successful login: 'user1@test.comr' (radicale_modoboa_auth_oauth2)
REPORT response status for '/user1@test.comr/jobs' with depth '1' in 2.438 seconds: 207 Multi-Status
Successful login: 'user1@test.comr' (radicale_modoboa_auth_oauth2)
REPORT response status for '/user1@test.comr/test1' with depth '1' in 2.980 seconds: 404 Not Found
...
thanx

<!-- gh-comment-id:3315427216 --> @nadihighlander commented on GitHub (Sep 21, 2025): I use haproxy for ssl endpoint and public ip I installed modoboa 2.5.1 on another server using local ip (using haproxy as reverse proxy) There are authorization errors in radicale log ... REPORT request for '/user1@test.comr/self' with depth '1' received from ::1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1' Access to '/user1@test.comr/self' denied for anonymous user REPORT response status for '/user1@test.comr/self' with depth '1' in 0.001 seconds: 401 Unauthorized REPORT request for '/user1@test.comr/jobs' with depth '1' received from 127.0.0.1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1' Access to '/user1@test.comr/jobs' denied for anonymous user REPORT response status for '/user1@test.comr/jobs' with depth '1' in 0.001 seconds: 401 Unauthorized REPORT request for '/user1@test.comr/test1' with depth '1' received from ::1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1' Access to '/user1@test.comr/test1' denied for anonymous user REPORT response status for '/user1@test.comr/test1' with depth '1' in 0.002 seconds: 401 Unauthorized REPORT request for '/user1@test.comr/self' with depth '1' received from 127.0.0.1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1' REPORT request for '/user1@test.comr/jobs' with depth '1' received from ::1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1' REPORT request for '/user1@test.comr/test1' with depth '1' received from 127.0.0.1 (forwarded for '11.11.11.11, 172.16.1.191') using 'python-caldav/2.0.1' Successful login: 'user1@test.comr' (radicale_modoboa_auth_oauth2) REPORT response status for '/user1@test.comr/self' with depth '1' in 1.582 seconds: 207 Multi-Status Successful login: 'user1@test.comr' (radicale_modoboa_auth_oauth2) REPORT response status for '/user1@test.comr/jobs' with depth '1' in 2.438 seconds: 207 Multi-Status Successful login: 'user1@test.comr' (radicale_modoboa_auth_oauth2) REPORT response status for '/user1@test.comr/test1' with depth '1' in 2.980 seconds: 404 Not Found ... thanx
Author
Owner

@tonioo commented on GitHub (Sep 22, 2025):

There are authentication issues. Can you check if radicale configuration contains a token url?

<!-- gh-comment-id:3317608718 --> @tonioo commented on GitHub (Sep 22, 2025): There are authentication issues. Can you check if radicale configuration contains a token url?
Author
Owner

@nadihighlander commented on GitHub (Sep 22, 2025):

I did not change anything after installation (using installer), except some minor config in nginx a) ports are changed b) ssl is disabled (haproxy is the ssl endpoint)

I guess installation architecture (using haproxy as reverse proxy) is the root of this issue
Is there any config in radicale or radicale_modoboa_auth_oauth2 when the installation server is behind a reverse proxy ?

radicale config file

cat /etc/radicale/config

# This file was automatically installed on 2025-09-14T16:55:11.799809
# -*- mode: conf -*-
# vim:ft=cfg

# Config file for Radicale - A simple calendar server
#
# Place it into /etc/radicale/config (global)
# or ~/.config/radicale/config (user)
#
# The current values are the default ones


[server]

# CalDAV server hostnames separated by a comma
# IPv4 syntax: address:port
# IPv6 syntax: [address]:port
# For example: 0.0.0.0:9999, [::]:9999
#hosts = 127.0.0.1:5232

# Daemon flag
#daemon = False

# File storing the PID in daemon mode
#pid =

# Max parallel connections
#max_connections = 20

# Max size of request body (bytes)
#max_content_length = 10000000

# Socket timeout (seconds)
#timeout = 10

# SSL flag, enable HTTPS protocol
#ssl = False

# SSL certificate path
#certificate = /etc/ssl/radicale.cert.pem

# SSL private key
#key = /etc/ssl/radicale.key.pem

# CA certificate for validating clients. This can be used to secure
# TCP traffic between Radicale and a reverse proxy
#certificate_authority =

# SSL Protocol used. See python's ssl module for available values
#protocol = PROTOCOL_TLSv1_2

# Available ciphers. See python's ssl module for available ciphers
#ciphers =

# Reverse DNS to resolve client address in logs
#dns_lookup = True

# Message displayed in the client when a password is needed
#realm = Radicale - Password Required


[encoding]

# Encoding for responding requests
#request = utf-8

# Encoding for storing local collections
#stock = utf-8


[auth]

# Authentication method
# Value: none | htpasswd | remote_user | http_x_remote_user
type = radicale_modoboa_auth_oauth2

# Htpasswd filename
# htpasswd_filename = users

# Htpasswd encryption method
# Value: plain | sha1 | ssha | crypt | bcrypt | md5
# Only bcrypt can be considered secure.
# bcrypt and md5 require the passlib library to be installed.
# htpasswd_encryption = plain

# Incorrect authentication delay (seconds)
#delay = 1

oauth2_introspection_endpoint = https://radicale:0a99aaaa-9999-9990-a99a-a90aa9999999@mail.test.com/api/o/introspect/


[rights]

# Rights backend
# Value: none | authenticated | owner_only | owner_write | from_file
type = from_file

# File for rights management from_file
file = /etc/radicale/rights


[storage]

# Storage backend
# Value: multifilesystem
type = radicale_storage_by_index
radicale_storage_by_index_fields = dtstart, dtend, uid, summary

# Folder for storing local collections, created if not present
filesystem_folder = /srv/radicale/collections

# Lock the storage. Never start multiple instances of Radicale or edit the
# storage externally while Radicale is running if disabled.
#filesystem_locking = True

# Sync all changes to disk during requests. (This can impair performance.)
# Disabling it increases the risk of data loss, when the system crashes or
# power fails!
#filesystem_fsync = True

# Delete sync token that are older (seconds)
#max_sync_token_age = 2592000

# Close the lock file when no more clients are waiting.
# This option is not very useful in general, but on Windows files that are
# opened cannot be deleted.
#filesystem_close_lock_file = False

# Command that is run after changes to storage
# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s)
#hook =


[web]

# Web interface backend
# Value: none | internal
type = none


[logging]

# Logging configuration file
# If no config is given, simple information is printed on the standard output
# For more information about the syntax of the configuration file, see:
# http://docs.python.org/library/logging.config.html
#config = /etc/radicale/logging

# Store all environment variables (including those set in the shell)
#full_environment = False

# Don't include passwords in logs
#mask_passwords = True


[headers]

# Additional HTTP headers
#Access-Control-Allow-Origin = *

<!-- gh-comment-id:3318003761 --> @nadihighlander commented on GitHub (Sep 22, 2025): I did not change anything after installation (using installer), except some minor config in nginx a) ports are changed b) ssl is disabled (haproxy is the ssl endpoint) I guess installation architecture (using haproxy as reverse proxy) is the root of this issue Is there any config in radicale or radicale_modoboa_auth_oauth2 when the installation server is behind a reverse proxy ? radicale config file ``` cat /etc/radicale/config # This file was automatically installed on 2025-09-14T16:55:11.799809 # -*- mode: conf -*- # vim:ft=cfg # Config file for Radicale - A simple calendar server # # Place it into /etc/radicale/config (global) # or ~/.config/radicale/config (user) # # The current values are the default ones [server] # CalDAV server hostnames separated by a comma # IPv4 syntax: address:port # IPv6 syntax: [address]:port # For example: 0.0.0.0:9999, [::]:9999 #hosts = 127.0.0.1:5232 # Daemon flag #daemon = False # File storing the PID in daemon mode #pid = # Max parallel connections #max_connections = 20 # Max size of request body (bytes) #max_content_length = 10000000 # Socket timeout (seconds) #timeout = 10 # SSL flag, enable HTTPS protocol #ssl = False # SSL certificate path #certificate = /etc/ssl/radicale.cert.pem # SSL private key #key = /etc/ssl/radicale.key.pem # CA certificate for validating clients. This can be used to secure # TCP traffic between Radicale and a reverse proxy #certificate_authority = # SSL Protocol used. See python's ssl module for available values #protocol = PROTOCOL_TLSv1_2 # Available ciphers. See python's ssl module for available ciphers #ciphers = # Reverse DNS to resolve client address in logs #dns_lookup = True # Message displayed in the client when a password is needed #realm = Radicale - Password Required [encoding] # Encoding for responding requests #request = utf-8 # Encoding for storing local collections #stock = utf-8 [auth] # Authentication method # Value: none | htpasswd | remote_user | http_x_remote_user type = radicale_modoboa_auth_oauth2 # Htpasswd filename # htpasswd_filename = users # Htpasswd encryption method # Value: plain | sha1 | ssha | crypt | bcrypt | md5 # Only bcrypt can be considered secure. # bcrypt and md5 require the passlib library to be installed. # htpasswd_encryption = plain # Incorrect authentication delay (seconds) #delay = 1 oauth2_introspection_endpoint = https://radicale:0a99aaaa-9999-9990-a99a-a90aa9999999@mail.test.com/api/o/introspect/ [rights] # Rights backend # Value: none | authenticated | owner_only | owner_write | from_file type = from_file # File for rights management from_file file = /etc/radicale/rights [storage] # Storage backend # Value: multifilesystem type = radicale_storage_by_index radicale_storage_by_index_fields = dtstart, dtend, uid, summary # Folder for storing local collections, created if not present filesystem_folder = /srv/radicale/collections # Lock the storage. Never start multiple instances of Radicale or edit the # storage externally while Radicale is running if disabled. #filesystem_locking = True # Sync all changes to disk during requests. (This can impair performance.) # Disabling it increases the risk of data loss, when the system crashes or # power fails! #filesystem_fsync = True # Delete sync token that are older (seconds) #max_sync_token_age = 2592000 # Close the lock file when no more clients are waiting. # This option is not very useful in general, but on Windows files that are # opened cannot be deleted. #filesystem_close_lock_file = False # Command that is run after changes to storage # Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s) #hook = [web] # Web interface backend # Value: none | internal type = none [logging] # Logging configuration file # If no config is given, simple information is printed on the standard output # For more information about the syntax of the configuration file, see: # http://docs.python.org/library/logging.config.html #config = /etc/radicale/logging # Store all environment variables (including those set in the shell) #full_environment = False # Don't include passwords in logs #mask_passwords = True [headers] # Additional HTTP headers #Access-Control-Allow-Origin = * ```
Author
Owner

@tonioo commented on GitHub (Nov 13, 2025):

@nadihighlander Do you still encounter this with latest version?
Can you also check this doc: https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html?

<!-- gh-comment-id:3528073852 --> @tonioo commented on GitHub (Nov 13, 2025): @nadihighlander Do you still encounter this with latest version? Can you also check this doc: https://modoboa.readthedocs.io/en/latest/manual_installation/radicale.html?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/modoboa-modoboa#1889
No description provided.