Catch-all route for custom 404 Not Found response #
Build a Go web server without external dependencies — just the standard library.
In this short example, you’ll create a basic web server with a custom
fallback page to replace Go’s standard 404 not found response.
Again, we use http.NewServeMux() from the standard library. By
the end, you’ll have a working server with a custom fallback page.
Set up the fallback router #
From the
previous
tutorial, we learned about the /name/{tag} route pattern to
dynamically use path values. Today, we’ll catch all other routes that aren’t
specified. The only thing we need to do is create a
http.HandleFunc, catch all GET requests on
/, and return any response we want e.g.
fmt.Fprintf(w, "Custom 404 Not Found").
Example
mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Custom 404 Not Found")
})
It’s important to define the catch-all route at the top. The code may not
behave as expected if a more specific HandleFunc is declared
before it.
Complete Example #
package main
import (
"errors"
"fmt"
"net/http"
"os"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Custom 404 Not Found"))
})
// Add new handler(s) below
srv := &http.Server{
Addr: fmt.Sprintf(":%d", 8080),
Handler: mux,
}
err := srv.ListenAndServe()
if !errors.Is(err, http.ErrServerClosed) {
os.Exit(1)
}
}
Try It with curl #
Once your server is running, you can test it using:
You should see this response:
Custom 404 Not Found
Contributions
Special thanks to Patrick Henry Winston his book Make It Clear was instrumental in shaping this article. Looking ahead, I’ll be focusing on two projects: Beago, a Go framework for building LLM-powered applications, and Vona, a minimalist and lightweight starter kit that that utilises Pico for beautiful plug-and-play landing page UI blocks.