Broken links in static deployments currently fall back to a
generic web server 404 page, which leaves users on an orphaned
error page with no direct way to continue navigating the
documentation site. Add a dedicated not-found page so deployments
can serve a project-specific 404 instead.
It keeps the normal documentation layout around the error state so
users still have the search box, table of contents, footer links,
and a clear route back to the documentation root. The penguin
logo makes it less generic and adds character to what is
otherwise a frustrating page to encounter.
For translated documentation, generate 404 pages whose return
link keeps users inside the current translation instead of always
sending them back to the English root documentation.
Actual 404 handling remains a web server concern.
Signed-off-by: Rito Rhymes <rito@ritovision.com>
Assisted-by: Codex:GPT-5.4
---
V2 adds multi-language routing support.
For 404 handling to work in nginx, point the site root at the
built documentation tree and route missing paths to the
generated 404 pages, for example:
location / {
error_page 404 /404.html;
try_files $uri $uri/ =404;
}
For translated documentation subtrees, add matching location
blocks that serve the subtree-specific 404 page, for example:
location /translations/zh_CN/ {
error_page 404 /translations/zh_CN/404.html;
try_files $uri $uri/ =404;
}
Repeat that pattern for the other translation subtrees so missing
translated pages keep users inside the current translation
instead of sending them back to the English root documentation.
I've tested the setup locally with nginx for all present translations
and the routing works fine.
These screenshots show the generated 404 page being served live in
Chrome on desktop and mobile.
Desktop screenshot:
https://github.com/user-attachments/assets/085eff0b-8661-4919-a651-6109e505ff05
Mobile screenshot:
https://github.com/user-attachments/assets/85a171f7-c2ff-483d-bc35-6719202a70e1
The screenshots above are hosted in a GitHub issue. For
convenience, anyone is welcome to post additional screenshots
there and reference them from the mailing list for discussion of
this patch:
https://github.com/ritovision/linux-kernel-docs/issues/4
diff --git a/Documentation/conf.py b/Documentation/conf.py
index 679861503..32f3aa698 100644
--- a/Documentation/conf.py
+++ b/Documentation/conf.py
@@ -130,6 +130,17 @@ def config_init(app, config):
"The kernel development community",
"manual"))
+ # Generate the root 404 page and per-translation copies for full-doc builds.
+ config.html_additional_pages = {"404": "404.html"}
+ if os.path.samefile(kern_doc_dir, app.srcdir):
+ translations_dir = os.path.join(kern_doc_dir, "translations")
+ for lang in sorted(os.listdir(translations_dir)):
+ full = os.path.join(translations_dir, lang)
+ if not os.path.isdir(full):
+ continue
+
+ config.html_additional_pages[f"translations/{lang}/404"] = "404.html"
+
# helper
# ------
@@ -437,6 +448,10 @@ sys.stderr.write("Using %s theme\n" % html_theme)
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["sphinx-static"]
+# Generate a simple static 404 page. Serving it for missing paths is left to
+# the web server configuration.
+html_additional_pages = {}
+
# If true, Docutils "smart quotes" will be used to convert quotes and dashes
# to typographically correct entities. However, conversion of "--" to "—"
# is not always what we want, so enable only quotes.
diff --git a/Documentation/sphinx-static/custom.css b/Documentation/sphinx-static/custom.css
index db24f4344..c4d28e1d4 100644
--- a/Documentation/sphinx-static/custom.css
+++ b/Documentation/sphinx-static/custom.css
@@ -169,3 +169,72 @@ a.manpage {
font-weight: bold;
font-family: "Courier New", Courier, monospace;
}
+
+/* Center the 404 body copy without affecting normal pages.
+ * This minimum height ensures the footer remains positioned
+ * visibly at the bottom of the page despite most of the page
+ * being empty.
+ * 100% width allows for contained centering of inner contents */
+div.kernel-404-page {
+ align-items: center;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: center;
+ min-height: 90vh;
+ padding: 2rem 1rem;
+ width: 100%;
+}
+
+/* Group the content as a vertical stack */
+div.kernel-404-content {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ max-width: 28rem;
+}
+
+a.kernel-404-logo-link {
+ align-self: stretch;
+ border-bottom: none;
+}
+
+a.kernel-404-logo-link:hover {
+ border-bottom: none;
+}
+
+img.kernel-404-logo {
+ display: block;
+ height: auto;
+ margin-inline: auto;
+}
+
+div.kernel-404-content h1,
+div.kernel-404-content p {
+ margin: 0;
+}
+
+/* Make the header larger and more prominent. */
+div.kernel-404-content h1 {
+ font-size: 300%;
+}
+
+p.kernel-404-home {
+ margin-top: 0.5rem;
+ text-align: center;
+}
+
+@media screen and (max-width: 65em) {
+ /* Less viewport height because the mobile sidebar is taking
+ * up large chunk of the screen already */
+ div.kernel-404-page {
+ min-height: 40vh;
+ }
+
+ img.kernel-404-logo {
+ width: 70%;
+ }
+
+ div.kernel-404-content h1 {
+ font-size: 240%;
+ }
+}
diff --git a/Documentation/sphinx/templates/404.html b/Documentation/sphinx/templates/404.html
new file mode 100644
index 000000000..1222f3fe1
--- /dev/null
+++ b/Documentation/sphinx/templates/404.html
@@ -0,0 +1,22 @@
+{# SPDX-License-Identifier: GPL-2.0-only #}
+{% extends "layout.html" %}
+{% set path_parts = pagename.split('/') %}
+{% set home_doc = master_doc %}
+{% if path_parts|length >= 2 and path_parts[0] == 'translations' %}
+ {% set home_doc = path_parts[0] ~ '/' ~ path_parts[1] ~ '/index' %}
+{% endif %}
+{% set title = "404 Not Found" %}
+
+{% block body %}
+ <div class="kernel-404-page">
+ <div class="kernel-404-content">
+ <a class="kernel-404-logo-link" href="{{ pathto(home_doc) }}"
+ aria-label="Return home">
+ <img class="kernel-404-logo" src="{{ pathto('_static/logo.svg', 1) }}" alt="" />
+ </a>
+ <h1>404 Not Found</h1>
+ <p>The page you are searching for doesn't exist.</p>
+ <p class="kernel-404-home"><a href="{{ pathto(home_doc) }}">Return home</a></p>
+ </div>
+ </div>
+{% endblock %}
--
2.51.0
Rito Rhymes <rito@ritovision.com> writes: > Broken links in static deployments currently fall back to a > generic web server 404 page, which leaves users on an orphaned > error page with no direct way to continue navigating the > documentation site. Add a dedicated not-found page so deployments > can serve a project-specific 404 instead. > > It keeps the normal documentation layout around the error state so > users still have the search box, table of contents, footer links, > and a clear route back to the documentation root. The penguin > logo makes it less generic and adds character to what is > otherwise a frustrating page to encounter. > > For translated documentation, generate 404 pages whose return > link keeps users inside the current translation instead of always > sending them back to the English root documentation. > > Actual 404 handling remains a web server concern. > > Signed-off-by: Rito Rhymes <rito@ritovision.com> > Assisted-by: Codex:GPT-5.4 I don't think that this makes a lot of sense. Who are your users, what is your use case? Who do you think will do all of the setup work to create a server with a custom 404 page, but can't supply the page itself? This is the kernel documentation, not a web-site construction kit. Please slow down and think about solving real problems. There is So Much Work that needs to be done with the kernel documentation, but none of it has to do with this stuff. And, in any case, the merge window is approaching, so significant changes will not be accepted at this point even if they otherwise make sense. Thanks, jon
> Who are your users, what is your use case? Who do you think will do all > of the setup work to create a server with a custom 404 page, but can't > supply the page itself? I see I framed this far too generically. My intent was narrower. I mentioned nginx because I had looked at the live docs.kernel.org deployment and saw that it uses nginx. The patch is intended primarily for the canonical live documentation site. My reasoning is that, on a public site of this size, users will still sometimes arrive at missing URLs through stale indexed links, old bookmarks, mistyped paths, truncated URLs, or references from external sites. In that case, a documentation-native 404 gives them a way back into search, site navigation, and the documentation root instead of leaving them on a generic orphaned server error page. The translated 404 handling also follows a live-site purpose. When a user lands on a missing page under translated documentation, it is more useful to keep the recovery path within that same language section than to send them back to the English root. Rito
© 2016 - 2026 Red Hat, Inc.