The entire .kp country domain stopped resolving worldwide. This is how
37 of its websites were reconstructed anyway - from the Internet Archive, by walking each site's
own link graph - and what the crawl exposed about how the country's web is actually shaped.
The site that started this was airkoryo.com.kp. It produced a name-resolution
error, which reads like "the site is down". It wasn't:
$ dig +short airkoryo.com.kp # nothing, from every resolver $ dig +short @8.8.8.8 airkoryo.com.kp # nothing $ curl --resolve www.airkoryo.com.kp:80:175.45.176.69 http://www.airkoryo.com.kp/ HTTP/1.1 200 OK 13,110 bytesAir Koryo
Same server, reached by raw IP, answered in ~25 seconds at 0.5 KB/s. So the web server was alive the whole time; only the lookup was broken. That reframed the problem: this was not an outage to wait out, it was an address book that had been withdrawn.
The root zone still delegates kp. - that part is intact. It points at
ns1.kptc.kp and ns2.kptc.kp, which live at
175.45.176.15 and .16, inside the same /22 block as the websites
themselves. Probe those nameservers directly and the shape of the problem appears:
$ dig @175.45.176.15 kp. +tcp -> NOERROR (responds) $ dig @175.45.176.15 kcna.kp +tcp -> SERVFAIL (children don't) $ dig @175.45.176.15 kp. +udp -> timeout (UDP/53 filtered) $ Cloudflare DoH -> EDE(22): No Reachable Authority at delegation kp
UDP/53 is filtered outright; TCP/53 answers only for the apex. Because the authoritative
servers sit inside the very link that gets closed, resolvers worldwide cannot reach the authority
for any child name - and when that happens, every .kp host vanishes
simultaneously, not just the one you asked for. That is why it looked like "North Korea's
internet went down" instead of "one site broke".
.kp slice on the public internet is the small foreign-facing edge of
a system whose bulk has never been reachable from outside.No zone transfer is possible, so the host list had to be assembled from three independent
sources: the public DPRK-website trackers, passive-DNS history, and institutions whose domains
appear in archived links. That produced 44 candidate hosts. Then each was queried against
the Wayback CDX index - twice, because the first pass used a prefix match that silently missed
everything archived under www.:
44 candidates → 37 with real captures (84,841 URLs indexed) → 7 with nothing at all
The seven - kiyctc, knic, cooksfriends,
korelcfund, ryongnamsan.edu, silibank,
star-co - were never crawled by anyone. No archive can contain them; live capture is
the only route and the door is shut.
The first mirror engine sampled URLs straight out of the CDX index and produced nonsense -
/ar/, ?utm_source= fragments, login redirects. The second walked
breadth-first from each site's real front page, following only links the site itself exposes.
That is what makes the mirror browse like a site instead of a pile of pages.
for each host: seeds = /, /index.html, www./, :80 variants, every netloc the CDX knows BFS = 45 pages, depth 2, same-host only assets = up to 220 per site, fetched 3-way parallel rewrite = strip web.archive.org wrappers, relativise /root-absolute refs verify = re-parse every saved page, resolve each local ref against disk
Two details matter more than they look. Archive URLs come back with the port baked into the
host (www.rodong.rep.kp:80), and pages are stored under their original
web/<timestamp>id_/<url> wrapper - both have to be normalised or every
link inside the mirror points back at the live archive instead of the local file.
| Symptom | Cause | Fix |
|---|---|---|
| One site had 45 pages but a single file on disk | Every article URL was index.php?newsID=...; the query was truncated to 36
characters, so all 45 IDs collapsed onto one filename and overwrote each other |
Hash-suffix the full query; 1 file became 79 |
| Whole sites rendered with no CSS or images | Host comparison used the raw netloc, so host:80 never matched
host - every asset was rejected as off-site |
Compare .hostname only, never the netloc |
| Ten sites reported as "never archived" | Archive.org signals rate-limits with a TCP connection refused, not a 429. The logger recorded that as an empty archive | Treat connect-failure as throttle: back off 20-90 s, retry 4x |
The third one is the one worth dwelling on. It produced a confident, wrong conclusion - "these sites don't exist in any archive" - for sites that turned out to be among the largest in the set, including the Pyongyang Times and Kim Chaek University of Technology. The mistake wasn't a crash; it was a log line that couldn't distinguish absent from busy. After the backoff fix, failed URLs per site dropped from 198 to 6, and coverage went from 27 sites to 37.
The domain space is a map of the state rather than a market. There is no e-commerce layer, no blogs, no shops - every site is an institution publishing on its own behalf:
| Suffix | Sites | What lives there |
|---|---|---|
.com.kp | 14 | trading companies, book and music sellers, the airline |
.org.kp | 7 | friendship societies, funds, professional associations |
.rep.kp | 5 | state organs - the news agency, party paper, radio, youth league |
.edu.kp | 5 | universities |
.gov.kp | 3 | ministries |
.aca.kp / .sca.kp / .law.kp | 3 | academy of sciences, arts collection, a law office |
outside .kp | 3 | overseas solidarity groups on foreign domains |
Two things follow from the capture dates. First, much of this is archaeology: the party newspaper's last snapshot is 2016, one of the big periodical archives stops in 2021, and a general-news site in 2024. The foreign-facing web peaked around 2010-2016 and has been going quiet on the same hardware ever since. Second, page counts are not article counts - the largest sites in the set are scanned-book and periodical libraries, where one "page" is a document record, not a story. The wire services are where the daily copy is.
| Measure | Value | How it was checked |
|---|---|---|
| Candidate hosts enumerated | 44 | trackers + passive DNS + archived links |
| Hosts with captures | 37 | CDX matchType=domain, throttle-aware retries |
| Hosts with no archive | 7 | 4 attempts each, all empty (not refused) |
| URLs indexed | 84,841 | inventory.json |
| Pages saved | 1,255 | per-site _manifest.json |
| Files on disk | 5,752 | find over the mirror tree |
| Local refs resolving | 73.8% | re-parse + filesystem resolve, per page |
| Live door status | shut | 14/14 probes to the /22 on 80/443 refused |
Three obvious continuations, in the order they'd pay off. A door watcher: the link opens occasionally - one 13 KB fetch of the airline site succeeded - so a low-frequency prober could grab live copies of the seven unarchived hosts the moment they answer. Deep mode on the sites that matter most, raising the cap from 45 pages to the full index for the wire services and the party paper. And full asset capture for the four sites missing stylesheets, if the archive ever backfills them.
The whole pipeline - recon, crawl, rewrite, verify - is documented and rerunnable. The archive this page describes is browsable at the portal.