django/django · warning · Http404

Page %s empty

Error message

Page %s empty

What it means

Raised as Http404 when the paginator for a sitemap section raises `EmptyPage`, i.e. the requested `?p=N` query parameter exceeds the number of available pages. The sitemap view paginates each section's URLs, so requesting a page beyond the last produces a 404 instead of an empty list.

Source

Thrown at django/contrib/sitemaps/views.py:125

        maps = sitemaps.values()
    page = request.GET.get("p", 1)

    lastmod = None
    all_sites_lastmod = True
    urls = []
    for site in maps:
        try:
            if callable(site):
                site = site()
            urls.extend(site.get_urls(page=page, site=req_site, protocol=req_protocol))
            if all_sites_lastmod:
                site_lastmod = getattr(site, "latest_lastmod", None)
                if site_lastmod is not None:
                    lastmod = _get_latest_lastmod(lastmod, site_lastmod)
                else:
                    all_sites_lastmod = False
        except EmptyPage:
            raise Http404("Page %s empty" % page)
        except PageNotAnInteger:
            raise Http404("No page '%s'" % page)
    # If lastmod is defined for all sites, set header so as
    # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
    if all_sites_lastmod:
        headers = {"Last-Modified": http_date(lastmod.timestamp())} if lastmod else None
    else:
        headers = None
    return TemplateResponse(
        request,
        template_name,
        {"urlset": urls},
        content_type=content_type,
        headers=headers,
    )

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Verify the requested page number is within site.paginator.num_pages (start at p=1).
  2. Ensure the section's queryset/items() actually returns at least one page of results.
  3. Regenerate and resubmit the sitemap index so crawlers only see valid page numbers.

Example fix

// before - request /sitemap.xml?section=blog&p=99 when only 3 pages exist -> 404 'Page 99 empty'

// after - link only valid pages
for page in range(1, sitemap.paginator.num_pages + 1):
    url = f"/sitemap.xml?section=blog&p={page}"
Defensive patterns

Strategy: validation

Validate before calling

def valid_page(p, num_pages):
    return p.isdigit() and 1 <= int(p) <= num_pages

# before building a sitemap URL
page = request.GET.get('p', '1')
if not valid_page(page, site.paginator.num_pages):
    raise Http404('Page %s empty' % page)

Type guard

def page_within_bounds(p, paginator) -> bool:
    try:
        n = int(p)
    except (TypeError, ValueError):
        return False
    return 1 <= n <= paginator.num_pages

Try / catch

from django.core.paginator import EmptyPage
from django.http import Http404

try:
    urls = site.get_urls(page=page, site=req_site, protocol=req_protocol)
except EmptyPage:
    raise Http404('Page %s empty' % page)

Prevention

When it happens

Trigger: A GET to a sitemap section URL with ?p=N where N is greater than site.paginator.num_pages, or N references a page that has no items because the queryset shrank since the index was generated.

Common situations: Search engines following cached links to old pages after content was deleted; manual testing with arbitrary ?p= values; a section whose queryset became empty so even page 1 is empty.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/3dc1af8a2700202b. Report an issue: GitHub.