Kleinanzeigen: a re-check returned deleted ads as live rows
Postmortem, 2026-10-08 to 2026-10-13: what broke, the impact, the fix, and what changed.
Date:
Affected: kleinanzeigen-scraper
Duration: 8 October to 13 October 2026; fixed build live 13 October
What happened
The listingIds input, which re-reads listings you already know instead
of searching, shipped on 8 October. On 12 October a customer re-checked a list of ads
on a schedule and one that the site had shown as deleted ("Gelöscht") all day came
back as a live row, with its title and price.
We confirmed it the next morning. Kleinanzeigen serves a deleted ad as a full page; the only trace of the deletion is a flag in the page's own script configuration, from which the browser paints the "Gelöscht" veil. Our check for a removed ad knew only the site's other way of removing one, a redirect to the homepage, so it read the page as a live ad.
Impact
Between 8 and 13 October, a re-check of an ad the site had deleted and still served as a page returned it as a live row and charged it. An expired ad could do the same. Searches were not affected: a deleted ad does not appear in search results.
We cannot say how many runs this affected. Runs execute in our customers' own Apify accounts, and we do not see their inputs. One customer reported one ad. If a re-check of yours in that window returned an ad that was already gone, open an issue on the actor's Issues tab with the run, and we will look at the charge with you.
Root cause
The site removes an ad in two ways and we had modelled one. Our test for "gone" used an old removed id, which takes the redirect path; an ad deleted recently takes the page path, which looks like a live ad to anything that does not read the flag.
Fix
Shipped 13 October (build 0.1.63). The actor reads the page's state flags: a deleted
or expired ad is skipped, named in the log and in the run status, and not charged.
Every ad read from its own page now carries status. A second report the
same day, a reserved ad, was covered in build 0.1.64: it comes back as a normal row
with status reserved. The customer's ad, with the seller's details
replaced, is now a test fixture.
What changed so it cannot recur this way
The live check for every "gone" verdict in the catalogue now uses a listing that was just removed, not an old id, so a second removal path cannot pass unseen again; and the fixture fails the build if the page shape changes.
Questions about this incident? contact@lowlanddata.com - reports get read the same day.