I have been generating private podcast feeds and learned that “valid XML” is only the first layer of compatibility. A feed can pass a validator and still behave strangely when a client refreshes, resumes an episode, or compares old and new items.
This is the checklist I now work through:
• Keep each item’s GUID stable forever. Changing it makes clients treat an edited episode as a brand-new episode.
• Keep enclosure URLs stable when the underlying episode has not changed. Use a new URL intentionally when the media really is a new revision.
• Include the enclosure length and a correct MIME type. Do not guess audio/mpeg for every file.
• Use absolute URLs everywhere a client must fetch something, including artwork and enclosures.
• Emit pubDate in an RFC 822-compatible format and keep time zones explicit.
• Support both common iTunes duration shapes. Some feeds use total seconds, while others use HH:MM:SS.
• Escape XML attribute values separately from element text. An ampersand inside an enclosure URL can break a feed in a way that is easy to miss when inspecting it visually.
• Put rich descriptions through one deliberate HTML path. Either escape the markup as text or wrap it correctly in CDATA. Mixing approaches produces double-escaped descriptions.
• Preserve useful podcast namespaces and tags when transforming an existing feed. Dropping unknown-but-valid metadata can remove chapters, transcripts, funding links, or alternate enclosures.
• Keep item ordering deterministic. A refresh should not reshuffle old episodes simply because unrelated metadata changed.
• Serve the media with GET, HEAD, byte ranges, Content-Length, and the correct Content-Type. Feed correctness and enclosure-server correctness are one compatibility problem.
• Add ETag or Last-Modified to the feed response so clients can refresh efficiently and receive 304 when nothing changed.
• Test refresh, seek, resume, artwork, and an edited episode in more than one client. Initial subscription is the easiest path and catches the fewest problems.
The big lesson for me was that podcast RSS is a long-lived identity contract, not just a current XML document. Stable IDs and predictable HTTP behavior matter as much as the tags.
What compatibility detail have you found that validators rarely warn about?
submitted by /u/robert_kr