When a calendar-query REPORT includes a prop-filter on CLASS with negate-condition="yes" and text-match value PRIVATE, the server drops events that have no CLASS property at all. Per RFC 5545 §3.8.5.1, the absence of CLASS on a VEVENT means the event is PUBLIC. The negate-condition filter should therefore only exclude events explicitly marked CLASS:PRIVATE, not events where CLASS is absent.
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
<c:comp-filter name="VEVENT">
<c:prop-filter name="CLASS">
<c:text-match negate-condition="yes">PRIVATE</c:text-match>
</c:prop-filter>
<c:time-range start="20260808T000000Z" end="20260905T235959Z" />
</c:comp-filter>
</c:comp-filter>
</c:filter>
</c:calendar-query>
Spec references
RFC 5545 §3.8.5.1 (CLASS): "The property MUST contain one of the following values: … If the property is not present, the value of CLASS is assumed to be PUBLIC."
RFC 5545 §3.8.5.1 (continuation): "Note: In this specification and in [RFC2446], the CLASS property is defined as an optional property. Implementers SHOULD provide a mechanism for changing the CLASS of a single calendar event… The absence of this property indicates a value of PUBLIC."
RFC 4791 §7.2 (prop-filter / text-match): "negate-condition … specifies that the filter test is negated, i.e., the filter matches if the property value does NOT match the text-match value." — A non-existing property does not match PRIVATE, so the negation should be true.
When a calendar-query REPORT includes a prop-filter on CLASS with negate-condition="yes" and text-match value PRIVATE, the server drops events that have no CLASS property at all. Per RFC 5545 §3.8.5.1, the absence of CLASS on a VEVENT means the event is PUBLIC. The negate-condition filter should therefore only exclude events explicitly marked CLASS:PRIVATE, not events where CLASS is absent.
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
<c:comp-filter name="VEVENT">
<c:prop-filter name="CLASS">
<c:text-match negate-condition="yes">PRIVATE</c:text-match>
</c:prop-filter>
<c:time-range start="20260808T000000Z" end="20260905T235959Z" />
</c:comp-filter>
</c:comp-filter>
</c:filter>
</c:calendar-query>
Spec references
RFC 5545 §3.8.5.1 (CLASS): "The property MUST contain one of the following values: … If the property is not present, the value of CLASS is assumed to be PUBLIC."
RFC 5545 §3.8.5.1 (continuation): "Note: In this specification and in [RFC2446], the CLASS property is defined as an optional property. Implementers SHOULD provide a mechanism for changing the CLASS of a single calendar event… The absence of this property indicates a value of PUBLIC."
RFC 4791 §7.2 (prop-filter / text-match): "negate-condition … specifies that the filter test is negated, i.e., the filter matches if the property value does NOT match the text-match value." — A non-existing property does not match PRIVATE, so the negation should be true.