| Internet-Draft | iCalendar Property Dependencies | March 2026 |
| Kashyap | Expires 29 September 2026 | [Page] |
RFC 5545 defines inter-property interaction rules for iCalendar components in prose scattered across multiple RFC sections. No published, standalone representation of these rules exists in a form suitable for machine consumption. This document specifies a formal dependency graph for VEVENT components with 27 properties and 20 edges spanning six edge types. It classifies properties into five merge safety categories that determine whether concurrent edits can be combined without user intervention. The specification is published as YAML and JSON artifacts for cross-language consumption.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 29 September 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
CalDAV [RFC4791] treats calendar resources as opaque blobs. Clients PUT entire iCalendar objects; servers use ETags for conflict detection. When two clients modify the same event, the only options are whole-event replacement or manual resolution. Property-level merge is not part of the protocol.¶
The barrier to property-level merge is not algorithmic. Three-way merge for structured data is well understood. The barrier is that [RFC5545] property dependencies are implicit: changing DTSTART can invalidate RRULE expansion, EXDATE membership, and VALARM trigger offsets, but this is expressed only in prose across separate RFC sections. Without a formal model of which properties depend on which, a merge engine cannot determine whether two concurrent edits are safe to combine.¶
This document extracts these implicit dependencies into a formal graph for VEVENT components and classifies each property by merge safety.¶
This specification covers VEVENT properties only. VTODO and VJOURNAL have different dependency structures (e.g., the Tasks draft removes the VTODO DURATION-to-DTSTART requirement). Extension to other component types is future work.¶
The graph includes all VEVENT properties with non-trivial inter-property dependencies, plus commonly-edited safe properties. [RFC5545] Section 3.6.1 defines additional VEVENT properties with no inter-property dependencies that are omitted for brevity: ATTACH, COMMENT, CONTACT, RELATED-TO, and RESOURCES. All are safe with set cardinality and union merge semantics.¶
Single-property cardinality constraints (e.g., DTSTART is REQUIRED) and value-level constraints (e.g., DTEND datetime MUST be greater than or equal to DTSTART datetime) are not modeled. This graph captures structural and type-level dependencies only.¶
CalDAV resources can contain multiple VEVENTs sharing a UID: one master and zero or more exception VEVENTs (each identified by RECURRENCE-ID). This graph models properties within a single VEVENT, but three edges cross VEVENT boundaries. A merge engine consuming this graph MUST operate on the full UID group (all VEVENTs sharing a UID), not individual VEVENTs in isolation. Edges marked "cross_vevent" in the machine-readable artifact require this UID-group scope.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The following terms are used throughout this document:¶
The graph uses six edge types with the following semantics:¶
Each edge carries a strength indicating the RFC conformance level of the constraint it represents:¶
The following table lists the 20 inter-property edges. All edges derive from [RFC5545]. Additional RFCs ([RFC7986], [RFC5546], [RFC6047], [RFC6638]) contribute property definitions and scheduling semantics used in the merge safety classification (Section 6), but no edges in this table originate from those documents. Symmetric edges (type_consistency, mutually_exclusive_with) are listed on both participating properties, yielding 20 entries for 16 unique relationships.¶
| Source | Target | Type | Str. | Ref |
|---|---|---|---|---|
| RRULE | DTSTART | depends_on | must | S3.8.5.3 |
| EXDATE | DTSTART | type_cons. | must | S3.8.5.1 |
| EXDATE | RRULE | depends_on | adv. | S3.8.5.1 |
| RDATE | DTSTART | type_cons. | must | S3.8.5.2 |
| VALARM | DTSTART | depends_on | must | S3.8.6.3 |
| VALARM | DTEND | depends_on | must | S3.8.6.3 |
| VALARM | DURATION | depends_on | must | S3.8.6.3 |
| REC-ID | DTSTART | derived_from | info. | S3.8.4.4 |
| REC-ID | RRULE | depends_on | must | S3.8.4.4 |
| REC-ID | RDATE | depends_on | must | S3.8.4.4 |
| ATTENDEE | ORGANIZER | requires | must | S3.8.4.1 |
| DTEND | DURATION | mut_excl. | must | S3.6.1 |
| DTSTART | DURATION | computes_w. | info. | S3.8.2.5 |
| DURATION | DTSTART | depends_on | must | S3.8.2.5 |
| DTSTART | DTEND | type_cons. | must | S3.6.1 |
| DTSTART | EXDATE | type_cons. | must | S3.8.5.1 |
| DTSTART | RDATE | type_cons. | must | S3.8.5.2 |
| DTSTART | UNTIL | type_cons. | must | S3.3.10 |
| DTEND | DTSTART | type_cons. | must | S3.6.1 |
| DURATION | DTEND | mut_excl. | must | S3.6.1 |
Abbreviations: REC-ID = RECURRENCE-ID; type_cons. = type_consistency; mut_excl. = mutually_exclusive_with; computes_w. = computes_with; adv. = advisory; info. = informational. All references are to [RFC5545] sections.¶
VALARM is a sub-component nested inside VEVENT, not a VEVENT property. Its edges are modeled at the VEVENT level for merge safety purposes. A complete VALARM merge requires set-level comparison of sub-components, not scalar property diffing. The VALARM depends_on edges are conditional on each alarm's TRIGGER RELATED parameter: RELATED=START (the default) depends on DTSTART; RELATED=END depends on DTEND or, when DTEND is absent, on DURATION. A merge engine that unconditionally flags all VALARMs when DTEND changes will produce false positive conflicts for RELATED=START alarms.¶
The DURATION depends_on DTSTART edge ([RFC5545] Section 3.8.2.5) captures a non-obvious format constraint: if DTSTART uses the DATE value type (all-day event), DURATION MUST use dur-day or dur-week format (e.g., P1D, P2W), not time granularity (e.g., PT1H). Changing DTSTART from DATE-TIME to DATE requires validating the DURATION format.¶
RECURRENCE-ID lives on an exception VEVENT; its targets (RRULE, RDATE, DTSTART) live on the master VEVENT. These edges are marked "cross_vevent: true" in the machine-readable artifact. A merge engine MUST resolve these edges across the full set of VEVENTs sharing a UID.¶
COUNT and UNTIL are mutually exclusive within an RRULE value ([RFC5545] Section 3.3.10). This is captured as an internal constraint rather than an inter-property edge, because both are parameters of the RRULE value, not separate VEVENT properties.¶
Given two concurrent edits to the same event (local and remote), can a property be independently merged? This section classifies all 27 VEVENT properties into five categories.¶
Properties: SUMMARY, DESCRIPTION, LOCATION, URL, GEO, PRIORITY, CATEGORIES, COLOR ([RFC7986]), CLASS, TRANSP, STATUS.¶
No cross-property dependencies. Independent merge is always valid. If local changes SUMMARY and remote changes LOCATION, both edits can be kept without conflict.¶
STATUS is structurally safe but semantically hazardous. Auto-merging STATUS:CANCELLED with a concurrent SUMMARY edit produces a cancelled event with a new title. A merge engine SHOULD surface STATUS:CANCELLED as a manual-resolution candidate.¶
Properties: DTSTART, DTEND, DURATION, RRULE, EXDATE, RDATE, VALARM.¶
Can be merged if graph validation passes. For example, if local changes DTSTART and remote adds an EXDATE, the merge engine MUST verify that the EXDATE value type still matches the new DTSTART type.¶
Properties: ATTENDEE, ORGANIZER, REQUEST-STATUS.¶
When CalDAV Scheduling [RFC6638] is active, modifying these properties triggers scheduling messages per [RFC6047]. They MUST NOT be auto-merged.¶
On servers without [RFC6638] (e.g., Radicale, Baikal), ATTENDEE is dependent (requires ORGANIZER) and ORGANIZER is also dependent (removing ORGANIZER while ATTENDEEs are present violates the "requires" edge regardless of scheduling support). REQUEST-STATUS falls back to safe. The machine-readable artifact captures this via a "scheduling_fallback" field.¶
Properties: UID, CREATED, RECURRENCE-ID.¶
Set once within a VEVENT instance. MUST NOT be changed after initial creation. UID identifies the event ([RFC5545] Section 3.8.4.7). CREATED records creation time ([RFC5545] Section 3.8.7.1). RECURRENCE-ID identifies which occurrence of a recurrence series was modified ([RFC5545] Section 3.8.4.4).¶
Properties: SEQUENCE, DTSTAMP, LAST-MODIFIED.¶
Automatically set on any edit. DTSTAMP and LAST-MODIFIED are set to the current UTC time.¶
SEQUENCE has a non-trivial merge rule. If only one side changed significant properties, the merge engine SHOULD preserve that side's SEQUENCE. If both sides changed significant properties, the merge engine SHOULD use max(local, remote) + 1. If neither changed significant properties, the merge engine SHOULD use max(local, remote). A blind max + 1 on every merge causes the escalation loop documented in existing CalDAV client implementations.¶
Properties with cardinality "set" (EXDATE, RDATE, CATEGORIES, ATTENDEE, VALARM) hold multiple values. The merge safety classification determines whether a property can be independently merged with edits to other properties but does not specify how to merge concurrent edits to the same multi-valued property.¶
The machine-readable artifact includes a "merge_op" field for set properties: "union" (EXDATE, RDATE, CATEGORIES) for additive merge, or "conflict" (ATTENDEE, VALARM) for set-level comparison requiring manual resolution.¶
EXDATE union requires checking for corresponding exception VEVENTs on the same date before applying. Adding an EXDATE for a date that has an exception VEVENT produces conflicting signals (the occurrence is both excluded and replaced).¶
The dependency graph is published as structurally equivalent YAML and JSON files at <https://github.com/iCalDAV/ical-dependency-graph>. The YAML includes inline commentary; the JSON uses fields prefixed with underscore ("_note", "_schema") for annotations. Underscore-prefixed fields are non-normative.¶
Each property object contains:¶
The "version" field uses semantic versioning:¶
25 bugs were identified across 17 distinct open-source projects spanning 8 programming languages (JavaScript, Python, C, Java, PHP, Kotlin, C#, Vala) where the root cause is a violated property dependency. The bugs fall into three categories:¶
The EXDATE-type-must-match-DTSTART rule ([RFC5545] Section 3.8.5.1) alone accounts for 7 separate bugs across independent implementations. The RRULE-DTSTART interaction has bugs dating back to 2013. 13 of 25 bugs involve these same two rules across independent implementations.¶
Additionally, 7 major calendar libraries across 6 languages have documented cross-property validation gaps: ical4j (Java), ical.js (JavaScript), libical (C), Python icalendar (Python), sabre/vobject (PHP), rrule.js (JavaScript), and ical4android (Kotlin).¶
The full bug catalog with links to individual issues is available in the companion preprint [ICAL-DEP-GRAPH] and at the repository listed in Section 7.¶
This document formalizes existing constraints from [RFC5545] and related specifications. It does not introduce new protocol elements or modify existing ones.¶
Implementations that consume the dependency graph for automated merge operations SHOULD validate the graph artifact's integrity before use (e.g., by verifying a checksum or fetching from a trusted source). A modified graph could cause a merge engine to incorrectly classify unsafe merges as safe, producing invalid iCalendar objects.¶
The scheduling properties (ATTENDEE, ORGANIZER, REQUEST-STATUS) have side effects beyond the local event when CalDAV Scheduling [RFC6638] is active. A merge engine MUST NOT auto-merge scheduling properties without the user's explicit consent, as this could result in unintended scheduling messages being sent to other participants.¶
This document has no IANA actions.¶
The dependency rules formalized in this document were validated against 295+ tests across three codebases and six CalDAV servers (iCloud, Nextcloud, Radicale, Baikal, Stalwart, Zoho). The bug catalog was compiled from public GitHub issues across 17 open-source calendar projects.¶