Skip to content

PARTSTAT change on a single occurrence of a recurring event triggers METHOD:REQUEST re-invite to all other attendees #60452

@ndo84bw

Description

@ndo84bw

Bug description

When an attendee accepts or declines a single occurrence of a recurring event, a recurrence exception (VEVENT with RECURRENCE-ID) is created. This modification to the calendar object causes Nextcloud to send a METHOD:REQUEST email to all other attendees, even though nothing changed for them.

This does not happen for single (non-recurring) events, where a PARTSTAT change correctly results in only a METHOD:REPLY to the organizer.

Related: nextcloud/calendar#6535 (notification spam), nextcloud/calendar#7771 (accept creates recurrence exception instead of updating master PARTSTAT), nextcloud/calendar#7850 (recurring event exception handling), #60451 (iMIP mail body issues for recurring events).

Setup:

  • Calendar app: 6.4.0
  • dav: 1.36.0
  • All users on the same instance, invited via the internal user picker (principal-based scheduling).
  • Attendees use Thunderbird 128.x via CalDAV.
    Scenario 1: Attendee declines a single occurrence

User A creates a weekly recurring event "Weekly 3x" (3 occurrences), adds User B and User C as attendees. Both accept the series via Thunderbird. User B then declines only the 2026-05-12 occurrence via Thunderbird.

User A (organizer) receives a correct METHOD:REPLY with RECURRENCE-ID for 2026-05-12 and PARTSTAT=DECLINED. The mail says "User B has declined your invitation" with the correct date. This is correct.

User C (other attendee) receives a METHOD:REQUEST re-invite for the entire series:

METHOD:REQUEST
 
BEGIN:VEVENT
UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
DTSTART;TZID=Europe/Berlin:20260505T113000
RRULE:FREQ=WEEKLY;COUNT=3;BYDAY=TU
SUMMARY:Weekly 3x
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user-b@example.com
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user-c@example.com
ORGANIZER;CN=admin:mailto:user-a@example.com
END:VEVENT
BEGIN:VEVENT
UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
DTSTART;TZID=Europe/Berlin:20260512T113000
RECURRENCE-ID;TZID=Europe/Berlin:20260512T113000
ATTENDEE;PARTSTAT=DECLINED:mailto:user-b@example.com
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user-c@example.com
ORGANIZER;CN=admin:mailto:user-a@example.com
END:VEVENT

Thunderbird at User C: "admin has invited you to Weekly 3x"
Nextcloud mail body: "admin möchte dich zu 'Weekly 3x' einladen."

User C already accepted. Nothing changed for User C. This email provides no useful information.

Scenario 2: Attendee accepts a single occurrence

User A creates a daily recurring event, adds User B and User C. User C accepts a single occurrence via the Nextcloud Calendar web UI (which creates a recurrence exception due to nextcloud/calendar#7771).

Result: User B receives a METHOD:REQUEST re-invite. The mail says "admin would like to invite you to 'Daily Test'" with the date of the first occurrence (in the past).

Scenario 3: Attendee removes event from calendar

Same setup. User C deletes the event in Thunderbird.

Result: User B again receives a METHOD:REQUEST re-invite.

Control test: Accepting the entire series

User A creates a weekly recurring event, adds User B and User C. User B accepts the entire series via Thunderbird iMIP ("Accept all").

Result: User C does not receive any email. Only User A receives the METHOD:REPLY. This is the correct behavior.

Control test: Single (non-recurring) event

User A creates a single event, adds User B and User C. User B accepts via Thunderbird.

Result: User C does not receive any email. Only User A receives the METHOD:REPLY. This is the correct behavior.

Pattern:

Scenario Other attendees receive re-invite? Correct?
Single event: attendee accepts No Yes
Series: attendee accepts entire series No Yes
Series: attendee accepts single instance Yes No
Series: attendee declines single instance Yes No
Series: attendee deletes event Yes No

The re-invite is only triggered when the PARTSTAT change creates a recurrence exception (VEVENT with RECURRENCE-ID). Operations that do not create exceptions behave correctly.

Steps to reproduce

  1. User A creates a weekly recurring event in the Nextcloud Calendar web UI (e.g. 3 occurrences), adds User B and User C as attendees via the user picker.
  2. User B accepts the entire series via Thunderbird iMIP.
  3. User C accepts the entire series via Thunderbird iMIP.
  4. User B declines a single occurrence via Thunderbird.
  5. User C receives a METHOD:REQUEST re-invite email for the entire series.

Expected behavior

A PARTSTAT change by one attendee should only generate a METHOD:REPLY to the organizer. Other attendees should not receive any email, regardless of whether the change creates a recurrence exception internally.

With N attendees, every accept/decline on a single instance currently generates up to N-1 unnecessary emails. On an instance with ~600 users, this creates significant email noise.

Nextcloud Server version

33

Operating system

Debian/Ubuntu

PHP engine version

PHP 8.3

Web server

Apache (supported)

Database engine version

MySQL

Is this bug present after an update or on a fresh install?

Upgraded to a MAJOR version (ex. 31 to 32)

Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

What user-backends are you using?

  • Default user-backend (database)
  • LDAP/ Active Directory
  • SSO - SAML
  • Other

Configuration report

{
    "system": {
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "***REMOVED SENSITIVE VALUE***",
            "***REMOVED SENSITIVE VALUE***",
            "***REMOVED SENSITIVE VALUE***"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "mysql",
        "version": "33.0.3.2",
        "overwrite.cli.url": "***REMOVED SENSITIVE VALUE***",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "htaccess.RewriteBase": "\/",
        "maintenance_window_start": 1,
        "maintenance": false,
        "default_phone_region": "de",
        "mail_smtpmode": "smtp",
        "mail_smtpsecure": "ssl",
        "mail_sendmailmode": "smtp",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpauth": 1,
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "465",
        "theme": "",
        "loglevel": 2,
        "config_preset": 9,
        "app_install_overwrite": [
            "fairmeeting",
            "jitsi",
            "bbb"
        ],
        "memcache.local": "\\OC\\Memcache\\APCu"
    }
}

List of activated Apps

Enabled:
  - activity: 6.0.0
  - app_api: 33.0.0
  - bruteforcesettings: 6.0.0
  - calendar: 6.4.0
  - circles: 33.0.0
  - cloud_federation_api: 1.17.0
  - comments: 1.23.0
  - contacts: 8.4.5
  - contactsinteraction: 1.14.1
  - dashboard: 7.13.0
  - dav: 1.36.0
  - federatedfilesharing: 1.23.0
  - federation: 1.23.0
  - files: 2.5.0
  - files_downloadlimit: 5.1.0
  - files_pdfviewer: 6.0.0
  - files_reminders: 1.6.0
  - files_sharing: 1.25.2
  - files_trashbin: 1.23.0
  - files_versions: 1.26.0
  - firstrunwizard: 6.0.0
  - guests: 4.7.2
  - logreader: 6.0.0
  - lookup_server_connector: 1.21.0
  - mail: 5.7.15
  - nextcloud_announcements: 5.0.0
  - notifications: 6.0.0
  - oauth2: 1.21.0
  - password_policy: 5.0.0
  - photos: 6.0.0
  - privacy: 5.0.0
  - profile: 1.2.0
  - provisioning_api: 1.23.0
  - recommendations: 6.0.0
  - related_resources: 4.0.0
  - richdocuments: 10.1.3
  - serverinfo: 5.0.0
  - settings: 1.16.0
  - sharebymail: 1.23.0
  - support: 5.0.0
  - survey_client: 5.0.0
  - text: 7.0.1
  - theming: 2.8.0
  - twofactor_backupcodes: 1.22.0
  - twofactor_totp: 15.0.0
  - updatenotification: 1.23.0
  - user_status: 1.13.0
  - viewer: 6.0.0
  - weather_status: 1.13.0
  - webhook_listeners: 1.5.0
  - whiteboard: 1.5.8
  - workflowengine: 2.15.0
Disabled:
  - admin_audit: 1.23.0
  - bbb: 2.9.1 (installed 2.9.1)
  - calendar_resource_management: 0.12.1 (installed 0.12.1)
  - collectives: 4.4.0 (installed 4.4.0)
  - deck: 1.17.1 (installed 1.17.1)
  - encryption: 2.21.0
  - fairmeeting: 0.22.5 (installed 0.22.5)
  - files_external: 1.25.1
  - integration_mattermost: 3.1.0 (installed 3.1.0)
  - jitsi: 0.19.0 (installed 0.19.0)
  - richdocumentscode: 25.4.904 (installed 25.4.904)
  - riotchat: 0.20.0 (installed 0.20.0)
  - spreed: 23.0.4 (installed 23.0.4)
  - suspicious_login: 11.0.0
  - systemtags: 1.23.0 (installed 1.22.0)
  - tables: 2.1.1 (installed 2.1.1)
  - testing: 1.23.0
  - twofactor_nextcloud_notification: 7.0.0
  - user_ldap: 1.24.0

Nextcloud Signing status

No errors have been found.

Nextcloud Logs

 

Additional info

This is a test instance used for app development. The bug was reproduced using only the Calendar web UI and Thunderbird iMIP. No third-party apps are involved in the iMIP/iTIP code path.

Related issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions