Reported from a real subscription: an episode failed to play with "the
format of the data has not been recognized" on a cdn.netzpolitik.org/….jpg
URL, 272428 bytes — exactly the length the feed declared for a JPEG.
audio_url preferred an audio-typed enclosure but then fell back to *any*
media url, and a WordPress blog feed attaches each post's featured image as
an <enclosure>, structurally identical to a podcast enclosure apart from
type="image/jpeg". https://netzpolitik.org/feed/ is 25 items, 25 JPEG
enclosures, and no audio reference of any kind, so every post became an
episode that could not play.
An enclosure is now accepted when its type says audio, when the feed omits
the type (plenty of hand-rolled feeds do), or when a generic
application/octet-stream is backed by an audio file extension — and
rejected otherwise, so images and video are skipped. Audio-typed still
wins, so a show that publishes both plays as audio.
A feed with entries and no audio now says so ("this looks like a blog feed
rather than a podcast feed"): an empty listing explains nothing on its own.
No URL in the message — a feed URL is a credential.
Also raises DEFAULT_MAX_FEED_BYTES from 8 to 32 MiB. Logbuch:Netzpolitik,
559 episodes in, is a healthy 6.8 MiB: feeds carry their whole back
catalogue with full show notes, so the first cap would have started
refusing real feeds within a year or two. Still bounded, still enforced
while reading rather than after, still lowerable via max_feed_bytes.
Verified: 30 rssdy tests (5 new, over feed-rs's real entry shapes:
image-only, mixed image+audio, untyped, generic-with-extension,
generic-without, video), and both live feeds — netzpolitik.org/feed/ now
yields 0 episodes with the warning, logbuch-netzpolitik.de/feed/mp3
(-> feeds.metaebene.me/lnp/mp3) yields 559 audio/mpeg episodes whose
HH:MM:SS durations parse.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>