Does your link checker treat a 200 as proof that everything is fine? In practice, a server may forward you to the right page with a 301 even when part of the URL is wrong. To a checker that follows redirects, a wrong URL and a correct one produce exactly the same 200. This article sets out the blind spot and how to detect it, based on measurements taken on 4 August 2026.
curl on 4 August 2026. Behaviour can change when a service changes its implementation, so reproduce it yourself before relying on it. The steps are given in the article.
What link checking misses
Auditing an internal link list, the references inside articles, or a pile of bookmarks. When you want to verify mechanically that a URL is alive, most implementations do this:
- Send a GET (or HEAD) to the URL
- Follow redirects
- Record it as alive if the final status is 2xx
This detects whether a URL is broken, but not whether a URL is wrong. Those are different things. The first is the server returning 404; the second is the server helpfully forwarding you to the right place, so a wrong URL still returns 200.
Measured: a wrong username still returns 200
Services that put the author's name in the article URL make this especially likely. Using the slug of a real article on a technical article-sharing service and changing only the username segment of the path, the results were as follows (measured 4 August 2026).
| Shape of the requested URL | Status | Location |
|---|---|---|
| Correct author name + real slug | 200 | (none) |
| A different real author's name + real slug | 301 | The true author's URL (with ?redirected=1) |
| A username that does not exist + real slug | 301 | Same as above |
| Correct author name + a slug that does not exist | 404 | (none) |
The conclusion is unambiguous: this service resolves an article by its slug alone, and the username segment of the path carries no authority. Put in a username that does not exist, or a different real person's name, and you are absorbed by a 301 into the true owner's URL. Conversely, if the slug does not exist you get 404 even with the correct username.
To a checker that follows redirects, all of these are "final 200". A link with a mistyped username and a link left over from before the author renamed themselves look exactly as healthy as a correct one.
Why it matters
- You cannot notice a wrong owner. A link you believed pointed at person A's article may in fact be someone else's, and the 200 hides it.
- You cannot track renames. When a cited author changes their name, the link keeps working, so only the author name you display goes stale.
- URLs never converge on the canonical form. Search engines are told the right answer by the canonical tag, but your own link list stays stale. If you deduplicate or aggregate by URL string, the same article survives under several spellings.
- Copy-paste mistakes persist. A typo made while assembling a URL by hand never once turns red.
Detection method 1: compare the requested URL with the final URL
The simplest method, and it works on any service. Follow redirects, then check whether the final URL equals the original. With curl, %{url_effective} gives you the final URL.
# Print the final URL alongside the status curl -sL -o /dev/null \ -w 'status=%{http_code}\nfinal=%{url_effective}\n' \ "$URL" # Observe the 3xx directly, without following it curl -s -o /dev/null \ -w 'status=%{http_code}\nlocation=%{redirect_url}\n' \ "$URL"
Split the verdict like this and the blind spot disappears.
| Observation | Meaning | Treat as |
|---|---|---|
| 200, and final URL equals the original | The URL is correct and alive | OK |
| 200, but final URL differs | You were redirected; the stored URL is stale or wrong | Needs review (update the link to the final URL) |
| 3xx (observed without following) | Same as above | Needs review |
| 4xx / 5xx | Broken | NG |
When comparing, remember to ignore tracking query parameters the service adds. In the measurement above, the redirect target carries ?redirected=1. Compare the strings with that included and the link will be flagged as mismatched forever, even after you correct it. Strip the query, or remove known parameters, before comparing.
Detection method 2: verify ownership through a public API
Matching URLs still does not tell you whose article it is. Where a service offers a public API, the reliable check is to fetch the article list for a username and confirm that the slug you care about is in it. The service above has an endpoint that needed no authentication and returned JSON in this shape on 4 August 2026.
# List a user's articles (no authentication; measured 2026-08-04) curl -s "https://zenn.dev/api/articles?username=<name>&order=latest" # Response shape (excerpt) { "articles": [ { "slug": "66fc12c8dc1f61", "path": "/<name>/articles/66fc12c8dc1f61", "published_at": "2026-08-04T09:31:15.165+09:00", "article_type": "tech", "user": { "username": "<name>" } } ] }
That path is the canonical path of the article as that user's work. If a URL in your link list is not among them, you can conclude that the username is wrong, or that ownership of the article has moved. A status code can never tell you that.
Generalising: which part of a URL is the real key?
This is not a quirk of one service but a general property of URL design. On many sites a URL combines two kinds of component:
- The key: the part that uniquely identifies the resource (an article ID, a slug, a hash). Get it wrong and you get a 404.
- The decoration: the parts that exist for humans (username, category name, a romanised title, a date). Get these wrong and the server may still forward you to the right place.
Working out which parts of the URLs you monitor are key and which are decoration reduces both false positives and blind spots. Finding out is easy: deliberately break the part you believe is decoration and see whether you get a 404 or a 301. That is exactly what the measurement above did.
It also helps to look at the kind of redirect. A permanent move (301 or 308) means you should rewrite your stored link; a temporary one (302 or 307) means you should not. For an overview of status codes, see An Introduction to HTTP Status Codes.
Checklist
- Does your checker record the final URL, rather than only the status?
- Does it compare the original and final URLs, after stripping tracking query parameters?
- Does it treat 301 and 308 as needs updating rather than simply OK?
- Do you verify that person and category names inside a URL are correct by some means other than the URL?
- If your monitoring calls an API, have you settled on an interval, a User-Agent, caching and 429 handling?
How to reproduce the measurements (4 August 2026)
- Get a real article slug from the public API:
curl -s "https://zenn.dev/api/articles?order=latest" - Replace the username segment with (1) the correct name, (2) a different real user's name, and (3) a name that does not exist, then run
curl -s -o /dev/null -w '%{http_code} %{redirect_url}' - Replace the slug with a value that does not exist and repeat the observation
- Confirm that the
<link rel="canonical">of the redirected page points at the true owner's URL without the query string
All of the above were run by the author. A service's implementation can change, so this is not a permanent specification.
Frequently Asked Questions
If a link checker gets a 200, does that mean the URL is correct?
No. A service may be designed to redirect a partially wrong URL to the correct one with a 301. A checker that follows redirects sees a final status of 200, so a wrong URL looks just as healthy as a correct one.
How can I detect a wrong URL?
Compare the requested URL with the final URL. With curl, -w '%{url_effective}' gives you the final URL. Strip any tracking query parameters the service adds, such as ?redirected=1, before comparing. Observing the 3xx directly without following it also works.
How do I verify that the username inside a URL is correct?
A status code cannot tell you. Where the service offers a public API, fetch the article list for that username and check whether the slug you care about appears in it. If it does not, the username is wrong or ownership has moved.
How do I work out which parts of a URL can be wrong and still redirect?
Deliberately break the part you believe is decoration and see whether you get a 404 or a 301. The part that produces a 404 is the key used to look up the resource; the part that is absorbed by a 301 is human-facing decoration.