HTTP 410 Gone

Gone

HTTP 410 is Gone: the resource used to be here, has been removed on purpose, and isn’t expected back. RFC 9110 section 15.5.11 frames it as web maintenance: it tells the client that the owners would like links to it removed. A server doesn’t have to mark every removed resource this way, or keep answering 410 forever.

410, 404 or a redirect

removed on purpose, nothing replaces it     410
missing, or you'd rather not say            404
moved, or something replaces it             301 or 308 to the replacement
down for a while                            503

If a page has a successor, redirect to it: a 410 turns away visitors who could have been sent somewhere useful. RFC 9110 prefers 410 over 404 only when the server knows the absence is permanent.

Search engines

Google’s documentation says every 4xx except 429 is handled the same way: the URL is removed from the index. So 410 and 404 send Google the same signal. The difference matters to people and to other clients: a 410 records a decision, a 404 only an absence. Search 404 410 in the tool below to see both cards.

Retiring an API

410 is the honest last step of a deprecation. Announce the date first with the Sunset header from RFC 8594, which also defines a sunset link relation for the migration notes:

HTTP/1.1 200 OK
Sunset: Thu, 31 Dec 2026 23:59:59 GMT
Link: <https://example.com/docs/v2-migration>; rel="sunset"

Then, after that date, answer 410 with a body that points to the replacement:

HTTP/1.1 410 Gone
Content-Type: application/problem+json

{"title": "API v1 has been retired", "status": 410, "detail": "Use /v2/orders; see https://example.com/docs/v2-migration"}

Clients should stop calling and drop the URL; retrying a 410 is pointless.

Caching

410 is heuristically cacheable (RFC 9110 section 15.1), so browsers and CDNs may keep it for a while with no Cache-Control at all. That suits something truly gone. If there’s any chance you’ll restore it, send a short max-age with the 410.

In your stack

location = /2019-holiday-sale { return 410; }
location ^~ /api/v1/ { return 410; }
Redirect gone /2019-holiday-sale
app.use('/api/v1', (req, res) => res.status(410).json({ error: 'gone', use: '/v2' }));   // Express
return HttpResponseGone()    # Django
abort(410)                   # Flask
http.Error(w, "this endpoint was retired; use /v2", http.StatusGone)

Try it in the HTTP Status Codes

410 Gone

  1. 410Gone4xx Client error

    The resource existed here and has been deliberately removed. Unlike 404, the server knows it is not coming back.

    When to use it

    Retired endpoints and deleted content you do not intend to restore, so clients and crawlers can drop them for good.

    Common mistakes

    Using it for something that moved, where a redirect serves the client better, and for temporary outages.

    Cacheable by defaultRFC 9110

Every code, by class

Codes marked unofficial come from one server’s own convention — nginx, Cloudflare, cPanel, Microsoft — and are not in the IANA registry.

Runs in your browser. Nothing you enter is sent anywhere.