Subscribed ICS calendars don't show up in the Web calendar app
Steps to reproduce
- Install Nextcloud with the Calendar app
- Subscribe to ICS calendars, eg. the web-shared version of an Outlook calendar
- Visit https://MYNEXTCLOUD/apps/calendar/dayGridMonth/now and see only the Nextcloud-hosted personal calendar entries, but no other entries
Expected behavior
The Nexcloud web calendar app should show the entries from the subscribed ICS calendars (as eg. the mobile phone calendar does for both calendars I subscribed to), for example for the teamup calendar (yellow in my calendar view) it should show
Actual behavior
Only the personal calendar shows up
Calendar app version
4.7.16
CalDAV-clients used
ICSx5 and DAVx5 (into Etar) for comparison
Browser
Qutebrowser 3.4.0, PaleMoon 33.7.0
Client operating system
Manjaro
Server operating system
Manjaro
Web server
Nginx
Database engine version
MariaDB
PHP engine version
PHP 8.1
Nextcloud version
Nextcloud Hub 7 (28.0.2)
Updated from an older installed version or fresh install
Fresh install
List of activated apps
Enabled:
- activity: 2.20.0
- calendar: 4.7.16
- circles: 28.0.0-dev
- cloud_federation_api: 1.11.0
- comments: 1.18.0
- contactsinteraction: 1.9.0
- dashboard: 7.8.0
- dav: 1.29.1
- federatedfilesharing: 1.18.0
- federation: 1.18.0
- files: 2.0.0
- files_pdfviewer: 2.9.0
- files_reminders: 1.1.0
- files_sharing: 1.20.0
- files_trashbin: 1.18.0
- files_versions: 1.21.0
- firstrunwizard: 2.17.0
- gpoddersync: 3.12.0
- logreader: 2.13.0
- lookup_server_connector: 1.16.0
- nextcloud_announcements: 1.17.0
- notifications: 2.16.0
- oauth2: 1.16.3
- password_policy: 1.18.0
- photos: 2.4.0
- privacy: 1.12.0
- provisioning_api: 1.18.0
- recommendations: 2.0.0
- related_resources: 1.3.0
- serverinfo: 1.18.0
- settings: 1.10.1
- sharebymail: 1.18.0
- support: 1.11.0
- survey_client: 1.16.0
- systemtags: 1.18.0
- text: 3.9.1
- theming: 2.3.0
- twofactor_backupcodes: 1.17.0
- updatenotification: 1.18.0
- user_status: 1.8.1
- viewer: 2.2.0
- weather_status: 1.8.0
- workflowengine: 2.10.0
Disabled:
- admin_audit: 1.18.0
- bruteforcesettings: 2.8.0
- contacts: 5.5.3
- encryption: 2.16.0
- files_external: 1.20.0
- suspicious_login: 6.0.0
- twofactor_totp: 10.0.0-beta.2
- user_ldap: 1.19.0
Nextcloud configuration
{
"system": {
"trusted_domains": [
"MYNEXTCLOUD",
"WHIMSICAL_LAN_HOSTNAME",
"localhost"
],
"overwrite.cli.url": "https:\/\/MYNEXTCLOUD\/nextcloud\/",
"htaccess.RewriteBase": "\/nextcloud\/",
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"loglevel": 0,
"logfile": "\/var\/log\/nextcloud\/nextcloud.log",
"apps_paths": [
{
"path": "\/usr\/share\/webapps\/nextcloud\/apps",
"url": "\/apps",
"writable": false
},
{
"path": "\/var\/lib\/nextcloud\/apps",
"url": "\/wapps",
"writable": true
}
],
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"dbtype": "mysql",
"version": "28.0.2.5",
"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***",
"data-fingerprint": "704389cb95dab9752eb564cdf8d57f1d",
"maintenance": false,
"maintenance_window_start": 3
}
}
Web server error log
Log file
The entire log has a lot of entries which I doubt are related (some are clearly not, eg. that one of my clients still has the wrong token from before the reinstall and is therefore on the block list. Noteworthy is the following type of entry which includes something about calendars.
{
"reqId": "e8ltkEmjRmGpklnOzD3A",
"level": 0,
"time": "2025-05-08T09:14:13+00:00",
"remoteAddr": "192.168.1.1",
"user": "Anaphory",
"app": "dav",
"method": "GET",
"url": "/nextcloud/ocs/v2.php/apps/user_status/api/v1/user_status?format=json",
"message": "No calendar events found for status check",
"userAgent": "Mozilla/5.0 (Linux) mirall/3.16.2daily (Nextcloud, manjaro-6.1.132-1-MANJARO ClientArchitecture: x86_64 OsArchitecture: x86_64)",
"version": "28.0.2.5",
"data": {
"app": "dav",
"user": "Anaphory"
}
}
Browser log
Additional info
Both subscriptions appear in select * from oc_calendarsubscriptions; – interestingly, the outlook calendar has refreshrate NULL, while the teamup calendar has refreshrate PT15M, and the second ID is 3 with a uri ending in -1 (I don't remember adding and removing a calendar in the experimentation process, but it could have happened?) but otherwise the table entries don't indicate any oddities.
MariaDB [nextcloud]> select id, uri, principaluri, displayname, refreshrate, calendarorder, calendarcolor, striptodos, stripalarms, stripattachments, lastmodified, synctoken from oc_calendarsubscriptions;
+----+---------------------+---------------------------+-----------------------+-------------+---------------+---------------+------------+-------------+------------------+--------------+-----------+
| id | uri | principaluri | displayname | refreshrate | calendarorder | calendarcolor | striptodos | stripalarms | stripattachments | lastmodified | synctoken |
+----+---------------------+---------------------------+-----------------------+-------------+---------------+---------------+------------+-------------+------------------+--------------+-----------+
| 1 | outlookoffice365com | principals/users/Anaphory | outlook.office365.com | NULL | 0 | #B6469D | NULL | NULL | NULL | 1746693678 | 379 |
| 3 | icsteamupcom-1 | principals/users/Anaphory | ics.teamup.com | PT15M | 0 | #D6B461 | NULL | NULL | NULL | 1746387592 | 43 |
+----+---------------------+---------------------------+-----------------------+-------------+---------------+---------------+------------+-------------+------------------+--------------+-----------+
I have checked one entry with calendarid 1, it is from my outlook calendar, because it has all the X-MICROSOFT keys and the SUMMARY:Mit Vorbehalt which is how Outlook exports my tentative appointments.
MariaDB [nextcloud]> select * from oc_calendarobjects where calendarid = 1 limit 1;
+-----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+------------+--------------+----------------------------------+------+---------------+----------------+---------------+------------------------------------------------------------------------------------------------------------------+----------------+--------------+------------+
| id | calendardata | uri | calendarid | lastmodified | etag | size | componenttype | firstoccurence | lastoccurence | uid | classification | calendartype | deleted_at |
+-----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+------------+--------------+----------------------------------+------+---------------+----------------+---------------+------------------------------------------------------------------------------------------------------------------+----------------+--------------+------------+
| 361 | BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Sabre//Sabre VObject 4.5.4//EN
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:W. Europe Standard Time
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:040000008200E00074C5B7101A82E00800000000D02EAE25DE7BDB01000000000000000
01000000044CB247448D906459447066ADA1BB638
SUMMARY:Mit Vorbehalt
DTSTART;TZID=W. Europe Standard Time:20250625T130000
DTEND;TZID=W. Europe Standard Time:20250626T160000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20250504T175138Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:1
X-MICROSOFT-CDO-APPT-SEQUENCE:1
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MICROSOFT-REQUESTEDATTENDANCEMODE:DEFAULT
X-MICROSOFT-ISRESPONSEREQUESTED:FALSE
END:VEVENT
END:VCALENDAR
| 0157b261-7613-440e-980a-9da3b95cda43.ics | 1 | 1746381123 | fa070d8117f2b0ff7a1cefb2f1fb42fa | 1191 | VEVENT | 1750849200 | 1750946400 | 040000008200E00074C5B7101A82E00800000000D02EAE25DE7BDB0100000000000000001000000044CB247448D906459447066ADA1BB638 | 0 | 1 | NULL |
+-----+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+------------+--------------+----------------------------------+------+---------------+----------------+---------------+------------------------------------------------------------------------------------------------------------------+----------------+--------------+------------+
Interesting, though: 1 is also the ID of the Contact birthdays calendar:
+----+---------------------------+-------------------+-------------------+-----------+-------------+---------------+---------------+----------+--------------+-------------+------------+
| id | principaluri | displayname | uri | synctoken | description | calendarorder | calendarcolor | timezone | components | transparent | deleted_at |
+----+---------------------------+-------------------+-------------------+-----------+-------------+---------------+---------------+----------+--------------+-------------+------------+
| 1 | principals/system/system | Contact birthdays | contact_birthdays | 1 | NULL | 0 | #E9D859 | NULL | VEVENT | 0 | NULL |
| 2 | principals/users/Anaphory | Personal | personal | 3 | NULL | 0 | NULL | NULL | VEVENT,VTODO | 0 | NULL |
+----+---------------------------+-------------------+-------------------+-----------+-------------+---------------+---------------+----------+--------------+-------------+------------+
The calendar entries have properly landed in the calendarobjects table.
MariaDB [nextcloud]> select calendarid, count(*) from oc_calendarobjects group by calendarid;
+------------+----------+
| calendarid | count(*) |
+------------+----------+
| 1 | 378 |
| 2 | 1 |
| 3 | 42 |
+------------+----------+
3 rows in set (0.003 sec)
I have checked one entry with calendarid 1, it is from my outlook calender (though 1 is also the ID of the Contact birthdays calendar. Calenadr ID 3 is only teamup.)
MariaDB [nextcloud]> select * from oc_calendars;
+----+---------------------------+-------------------+-------------------+-----------+-------------+---------------+---------------+----------+--------------+-------------+------------+
| id | principaluri | displayname | uri | synctoken | description | calendarorder | calendarcolor | timezone | components | transparent | deleted_at |
+----+---------------------------+-------------------+-------------------+-----------+-------------+---------------+---------------+----------+--------------+-------------+------------+
| 1 | principals/system/system | Contact birthdays | contact_birthdays | 1 | NULL | 0 | #E9D859 | NULL | VEVENT | 0 | NULL |
| 2 | principals/users/Anaphory | Personal | personal | 3 | NULL | 0 | NULL | NULL | VEVENT,VTODO | 0 | NULL |
+----+---------------------------+-------------------+-------------------+-----------+-------------+---------------+---------------+----------+--------------+-------------+------------+
I am happy to dig into more table entries. I can try to subscribe to test ICS files you point me to and report the results.
Hi @Anaphory
If you subscribe to one of the holiday calendars do they show properly?
Good idea! I subscribed to the German holiday calendar, which is not shown either.
Okay, interesting.
I just tested this on my dev setup with the German calendar and it did work properly.
Do you see any errors in the nextcloud log? When you add the holiday calendar
I removed the holiday calendar and added it again, with the same effect (no holidays showing up) and no surprising entries in the log, just
{
"reqId": "b2vUhYhfwXXbczWMblye",
"level": 0,
"time": "2025-05-09T19:53:41+00:00",
"remoteAddr": "192.168.1.1",
"user": "Anaphory",
"app": "dav",
"method": "MKCOL",
"url": "/nextcloud/remote.php/dav/calendars/Anaphory/holidays-in-germany-1",
"message": "Refreshing webcal data for subscription 5",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/6.9.0 Chrome/130.0.0.0 Safari/537.36",
"version": "28.0.2.5",
"data": {
"app": "dav"
}
}
{
"reqId": "b2vUhYhfwXXbczWMblye",
"level": 0,
"time": "2025-05-09T19:53:44+00:00",
"remoteAddr": "192.168.1.1",
"user": "Anaphory",
"app": "dav",
"method": "MKCOL",
"url": "/nextcloud/remote.php/dav/calendars/Anaphory/holidays-in-germany-1",
"message": "Scheduling webcal data refreshment for subscription 5",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/6.9.0 Chrome/130.0.0.0 Safari/537.36",
"version": "28.0.2.5",
"data": {
"app": "dav"
}
}
followed by a bunch of "No calendar events found for status check".
When I run occ maintenance:repair, even when I run it twice in a row, I always get two entries formatted as „doing something“ (white progress bars, where everything else is just the names and summaries in grey), and both are calendar related:
- Fix broken values of calendar objects
0 [->--------------------------]
[...]
- Clean up old calendar subscriptions from deleted users that were not cleaned-up
3/3 [============================] 100%
There should be no deleted users with unclean calendars (it was a new install this week), could this point to something relevant to this issue? (It does confirm that - 0 calendar subscriptions without an user have been cleaned up)
I have the same problem. Adding the Holidays for Germany calendar works fine, but a different ICS calendar doesn't. Events don't show in the web interface, but do show in other software connected to Nextcloud via CalDAV.
A public calendar affected by this bug can be found here: https://gruenekarlsruhe.de/?mec-ical-feed=1
I've also attached two files: The ICS file returned by the above URL at the time of writing and the ICS file returned by Nextcloud after first importing, then exporting the calendar (renamed to .txt because GitHub doesn't allow .ics files)
mec-events-20250628UTC1347.ics (original) gruenekarlsruhede-2025-06-28.ics (exported from Nextcloud)
Thanks @Anaphory and @freundTech for the additional information. I was able to reproduce the issue with the attached calendar.
Looks like there is anh issue with the date/time format, it is not valid in the linked calendar and our parser is crashing.
The CREATED property in the attached calendar indeed is malformed. As it is only "CREATED:20250519" but should be "CREATED:20250519T000000z" in UTC format according to the RFC.
https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.7.1
could not convert calendar object of calendar L3JlbW90ZS5waHAvZGF2L2NhbGVuZGFycy91c2VyMS9ncnVlbmVrYXJsc3J1aGVkZS8= Error: invalid date-time value: "2025-05-21T::"
fromDateTimeString ical.js:690
decorate ical.js:6364
_decorate ical.js:7451
_hydrateValue ical.js:7434
getFirstValue ical.js:7581
fromICALJs index.mjs:2434
fromICALJs index.mjs:4121
fromICALJs index.mjs:5996
fromICALJs index.mjs:4126
fromICALJs index.mjs:6862
_createCalendarComponent index.mjs:7377
parse index.mjs:7294
mapCDavObjectToCalendarObject calendarObject.js:57
getEventsFromCalendarInTimeRange calendars.js:685
wrappedAction pinia.mjs:1399
actionName pinia.mjs:932
events eventSource.js:49
unpromisify internal-common.js:4594
fetch index.js:891
fetchSource index.js:600
fetchSourcesByIds index.js:588
fetchDirtySources index.js:571
addSources index.js:563
reduceEventSources index.js:521
_handleAction index.js:1383
runTask index.js:1156
drain index.js:1148
drained internal-common.js:156
tryDrain internal-common.js:138
request internal-common.js:101
request index.js:1134
resetOptions index.js:1346
resetOptions index.js:2149
handler FullCalendar.js:99
VueJS 11
addCalendarMutation calendars.js:883
wrappedAction pinia.mjs:1399
actionName pinia.mjs:932
loadCollections calendars.js:207
loadCollections calendars.js:206
wrappedAction pinia.mjs:1399
actionName pinia.mjs:932
beforeMount Calendar.vue:220
VueJS 27
<anonymous> main.js:47
<anonymous> calendar-main.js:322648
<anonymous> calendar-main.js:322650
Object { response: {…} }
calendars.js:689
Thanks for investigating.
Are there two different parsers in use? I just noticed that the events do show in the "Upcoming Events" widget on the Nextcloud dashboard, but don't show in the actual calendar.
Also, do you think it would be acceptable to make the parser more permissive to accept those technically incorrect date-times? Alternatively, invalid properties could be ignored, or as a last resort, Nextcloud should at least notify the user that their calendar is faulty somehow.
According to the metadata the faulty calendar (at least the one I submitted) is generated by a WordPress plugin called "MEC". I'd guess it's this calendar plugin. Sadly it isn't Open Source, so I can't fix file generation and I don't have an account, so I can't contact support.
Are there two different parsers in use? I just noticed that the events do show in the "Upcoming Events" widget on the Nextcloud dashboard, but don't show in the actual calendar.
yes, there is a backend and frontend parser, the events are stored in raw ical format then pulled and parsed by the front end.
Also, do you think it would be acceptable to make the parser more permissive to accept those technically incorrect date-times? Alternatively, invalid properties could be ignored, or as a last resort, Nextcloud should at least notify the user that their calendar is faulty somehow.
We use a 3rd party library iCal.js, they stick to the RFC pretty closely. We can make a recommendation.
According to the metadata the faulty calendar (at least the one I submitted) is generated by a WordPress plugin called "MEC". I'd guess it's this calendar plugin. Sadly it isn't Open Source, so I can't fix file generation and I don't have an account, so I can't contact support.
I would submit a ticket and have them fix it.
I looked into the iCal.js code and noticed that they already support a more permissive mode. All that's needed is setting ICAL.design.strict = false.
I tested this by loading Nextcloud with a breakpoint set, changing strict to false, and pressing continue. The calendar loaded correctly and displayed the previously missing events.
Looking at the nextcloud code it looks like this should go into nextcloud/calendar-js instead of this repo. This repo imports ical.js once directly, but mostly uses it through nextcloud/calendar-js. That repo imports ical.js in many different places, so I'm not quite sure where the best place to put the change is.
@freundTech Instead of disabling ical.js strict mode writing a repair step should be more appropriate: https://github.com/nextcloud/calendar-js/tree/main/src/parsers/repairsteps/icalendar
I noticed those repair steps after submitting my PR. May I ask why writing a repair step is more appropriate? iCal.js lenient mode is designed for this exact scenario and will additionally solve other similar problems.
Solving it with a repair step seems like it would just be duplicate work. iCal lenient mode is also more powerful, because it works directly on the partially parsed data instead of doing simple string replacements.
I noticed those repair steps after submitting my PR. May I ask why writing a repair step is more appropriate? iCal.js lenient mode is designed for this exact scenario and will additionally solve other similar problems. Solving it with a repair step seems like it would just be duplicate work. iCal lenient mode is also more powerful, because it works directly on the partially parsed data instead of doing simple string replacements.
A repair step is technically the correct way to do it, Fixing the entries in the database to be RFC compliant is better as we try to be as strict with RFC compliance as possible but it is difficult to do when other apps create non complaint events.
As for the repair steps, you would not be able to use a conventional repair step these only run on updates. The subscribed calendars are refreshed every so often, so this would need to be done either during the refresh pull or with a background job. But it would be hard to find entries that need fixing with a back ground job, without opening them all. So the only option left is to fix them on refresh.
@SebastianKrupinski I didn't meant a Nextcloud "server" repair step, I meant a repair step in CalendarJS as linked above. The issue of importing an ICS in the calendar app is indeed different from fetching subscriptions in dav, but we could fix them in the same kind of way there.
@SebastianKrupinski I didn't meant a Nextcloud "server" repair step, I meant a repair step in CalendarJS as linked above. The issue of importing an ICS in the
calendarapp is indeed different from fetching subscriptions indav, but we could fix them in the same kind of way there.
Yes that is one of the ideas we discussed yesterday and the idea of making the CalJS less strict as a fall back if there is an error.
I think this might be the best approach at the moment, try parsing is strict mode and if there is a problem fall back to lement mode.
We'll have to wait for @st3iny to comment. In a couple weeks when he is back.
I agree with @tcitworld here. Enabling a global option on the ICAL object will likely cause side effects.
A repair step is more appropriate here.
Thanks for the contribution nevertheless.
I just tested the newly released Calendar 5.3.6 (which includes calendar-js 8.1.3) and noticed that at least for the reproducer I posted above https://github.com/nextcloud/calendar-js/pull/825 didn't fix the issue.
The problem seems to be that, in addition to CREATED wrongly using a date instead of a datetime, LAST-MODIFIED also wrongly uses a date instead of a datetime, causing the same exception to be thrown.
This means calendar-js either needs a second repair step dealing with the LAST-MODIFIED field, or the existing repair step needs to be extended to handle all multiple (all?) datetime valued fields.
@freundTech Thanks for the notice. Please have a look at https://github.com/nextcloud/calendar-js/pull/828.
I might have a similar problem: When i export my Outlook calender, i can import it as "standalone" calender, which works fine. But if I add the URL of the .ics, then the entries won't show.
Also when I fill the DAV url in my Thunderbird, the ics calendars from urls won't show there. Is this somehow related?
I might have a similar problem: When i export my Outlook calender, i can import it as "standalone" calender, which works fine. But if I add the URL of the .ics, then the entries won't show.
Also when I fill the DAV url in my Thunderbird, the ics calendars from urls won't show there. Is this somehow related?
Subscriptions are not exported to external clients at the moment. However, it is technically possible by setting the x-nc-caldav-webcal-caching: On header. Our CalDAV server will then export all events of the subscription. But AFAIK, only our Calendar app does that at the moment.
@st3iny I think my error comes from this bug: https://github.com/nextcloud/calendar/issues/7234 https://github.com/bitfireAT/icsx5/discussions/654#discussioncomment-14137171
Regarding that header: Where/how do I set it?
@st3iny I think my error comes from this bug: https://github.com/nextcloud/calendar/issues/7234 https://github.com/bitfireAT/icsx5/discussions/654#discussioncomment-14137171
Regarding that header: Where/how do I set it?
You can't, that is the point. For example on Android, there is a second app icsx5 to sync subscriptions.
This header is only meant to be used internally in Nextcloud Calendar.