How to Validate & Fix ICS Files Programmatically (Node, Python, Bash)
A practical guide for developers integrating calendar exports, ICS feeds, or user-uploaded .ics files
ICS (iCalendar) files are the standard format for calendar events — but real-world ICS files are often malformed, missing fields, or rejected by Google Calendar, Outlook, or Apple Calendar.
If your app:
- imports user-provided ICS files
- exports ICS files
- syncs events between vendors
- ingests ICS feeds
- uses ICS in CI/testing
…you’ll quickly run into subtle failures around:
- invalid DTSTART / DTEND
- TZID / time zone mismatches
- missing UID or PRODID
- malformed RRULE
- bad line endings or folding
- missing
BEGIN:VCALENDAR/END:VCALENDAR
This guide shows you how to automatically validate, lint, and autofix ICS files programmatically, using:
- Node.js
- Python
- Bash / cURL
All examples use the CorrectICS API, which provides:
- strict validation
- human-readable error messages
- auto-correction of common issues
- clean output compatible with Google, Outlook, and Apple Calendar
1. Why programmatic ICS validation is necessary
Manual checking of ICS files is not scalable:
- ICS parsers don’t validate strictly
- Google/Outlook silently reject some files
- Vendors output non-standard time zones
- RRULEs differ across clients
- Files can be long, folded, or deeply nested
If you’re ingesting ICS at scale (SaaS, marketplace integrations, booking systems), you need:
- consistent validation
- clear errors for debugging
- automatic fixes
- CI or ingestion pipeline support
2. API Overview: Validate vs Autofix
Validate endpoint
Checks ICS for:
- spec violations
- missing fields
- invalid time zones
- malformed RRULEs
- structural issues
Returns:
valid: true/false- list of errors, warnings, hints
Autofix endpoint
- repairs time zones
- inserts missing UID/PRODID
- fixes missing boundaries
- corrects RRULE errors
- normalizes line endings & folding
- returns a fixed
.icsfile
Used for ingestion pipelines or automated exports.
3. Quickstart (Bash / cURL)
Validate an ICS file
curl -X POST https://api.correctics.com/v1/validate \
-H "Content-Type: text/calendar" \
--data-binary @event.ics
Autofix an ICS file
curl -X POST https://api.correctics.com/v1/autofix \
-H "Content-Type: text/calendar" \
--data-binary @event.ics \
-o fixed.ics
Response example (validation)
{
"valid": false,
"errors": [
{
"code": "MISSING_DTSTART",
"message": "VEVENT is missing a DTSTART property",
"line": 12
},
{
"code": "INVALID_TZID",
"message": "TZID 'EST' is not a valid IANA timezone",
"line": 18
}
],
"warnings": []
}
4. Node.js Example — Validate an ICS File
No client library required — just use fetch (Node 18+):
npm init -y
validate.js
import { readFileSync } from 'fs';
async function validateICS(path) {
const data = readFileSync(path);
const res = await fetch('https://api.correctics.com/v1/validate', {
method: 'POST',
headers: { 'Content-Type': 'text/calendar' },
body: data,
});
const result = await res.json();
console.log(result);
}
validateICS('broken.ics');
Run:
node validate.js
5. Node.js Example — Autofix an ICS File
autofix.js
import { readFileSync, writeFileSync } from 'fs';
async function autofixICS(inputPath, outputPath) {
const data = readFileSync(inputPath);
const res = await fetch('https://api.correctics.com/v1/autofix', {
method: 'POST',
headers: { 'Content-Type': 'text/calendar' },
body: data,
});
const fixed = await res.text();
writeFileSync(outputPath, fixed);
console.log(`ICS file fixed and saved to ${outputPath}`);
}
autofixICS('broken.ics', 'fixed.ics');
6. Python Example — Validate an ICS File
Install:
pip install requests
validate.py
import requests
with open('broken.ics', 'rb') as f:
data = f.read()
res = requests.post(
'https://api.correctics.com/v1/validate',
headers={'Content-Type': 'text/calendar'},
data=data,
)
print(res.json())
7. Python Example — Autofix an ICS File
autofix.py
import requests
with open('broken.ics', 'rb') as f:
data = f.read()
res = requests.post(
'https://api.correctics.com/v1/autofix',
headers={'Content-Type': 'text/calendar'},
data=data,
)
with open('fixed.ics', 'wb') as f:
f.write(res.content)
print('Saved fixed.ics')
8. Validating ICS Files in CI (GitHub Actions)
Ideal for SaaS teams exporting ICS files. Add a CI step to ensure your ICS output is always valid.
.github/workflows/ics-check.yml
name: Validate ICS Files
on: [push]
jobs:
check-ics:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate ICS
run: |
for f in ./ics/*.ics; do
echo "Checking $f"
curl -s -X POST https://api.correctics.com/v1/validate \
-H "Content-Type: text/calendar" \
--data-binary @$f \
| grep '"valid":false' && exit 1 || true
done
This prevents invalid exports from reaching production.
9. Bulk Validation (Directory of ICS Files)
Bash
mkdir -p fixed
for f in *.ics; do
echo "Fixing $f"
curl -s -X POST https://api.correctics.com/v1/autofix \
-H "Content-Type: text/calendar" \
--data-binary @$f \
-o "fixed/$f"
done
Node
import fs from 'fs';
const files = fs.readdirSync('./ics');
for (const file of files) {
const data = fs.readFileSync(`./ics/${file}`);
const res = await fetch('https://api.correctics.com/v1/autofix', {
method: 'POST',
headers: { 'Content-Type': 'text/calendar' },
body: data,
});
fs.writeFileSync(`./fixed/${file}`, await res.text());
}
10. Common ICS issues this catches automatically
CorrectICS automatically detects and fixes:
- invalid time zones (e.g.,
TZID=EST) - missing
END:VEVENT/END:VCALENDAR - missing
DTSTARTorDTEND - invalid or infinite RRULEs
- missing UIDs
- bad line folding or encoding
- files with mixed line endings
- invalid UTF-8 characters
No more manual debugging.
11. When to integrate ICS autofix
You should add automated ICS validation when:
- users upload ICS from many vendors
- your SaaS exports ICS for calendar integrations
- you generate recurring events
- you import ICS from booking apps, CRMs, POS systems
- you sync with Outlook, Apple Calendar, Google Calendar
- you have calendar support tickets caused by broken files
If you see recurring complaints around time zones or recurring events, programmatic validation solves it permanently.
12. Conclusion
ICS issues are persistent, subtle, and vary across calendar platforms. Validating and autofixing ICS files programmatically:
- saves engineering time
- reduces user-facing errors
- prevents silent failures in Google/Outlook/Apple
- improves export/import reliability
- makes ICS integrations predictable
To get started:
👉 Try CorrectICS to validate or autofix ICS files →
👉 Use the API for CI, ingestion, or export pipelines