Creating an HTTP 404 handler for Go net/http servers

Featured image for sharing metadata for article

I've recently been writing some HTTP servers using Go's net/http package, and found that trying to add a 404 handler - by default - wasn't super straightforward.

As per the net/http documentation:

Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".

This means that if we register a handler for /, we can then check the incoming path of the request and see if it's not the root path.

This would allow us to write the following code:

package main

import (
	"fmt"
	"html"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/" {
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, "Error: handler for %s not found", html.EscapeString(r.URL.Path))
			return
		}

		fmt.Fprintln(w, "Welcome to / handler")
	})

	http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
	})

	log.Fatal(http.ListenAndServe(":8080", nil))
}

Which then handles requests like so:

% curl localhost:8080/
Welcome to / handler

% curl localhost:8080/ -i
HTTP/1.1 200 OK
Date: Thu, 11 May 2023 20:40:44 GMT
Content-Length: 21
Content-Type: text/plain; charset=utf-8

Welcome to / handler

% curl localhost:8080/not/there/ -i
HTTP/1.1 404 Not Found
Date: Thu, 11 May 2023 20:40:52 GMT
Content-Length: 40
Content-Type: text/plain; charset=utf-8

Error: handler for /not/there/ not found%

% curl localhost:8080/health -i
HTTP/1.1 200 OK
Date: Thu, 11 May 2023 20:40:55 GMT
Content-Length: 0

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #go.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.