diff --git a/crawler.go b/crawler.go
index 49d124bbafdffc13465da21636f3ef28183df20c..b2ad3d9208c8d6435a35f8bcc01e9adcffdb29a8 100644
--- a/crawler.go
+++ b/crawler.go
@@ -154,8 +154,8 @@ func normalizeURL(u *url.URL) *url.URL {
 			purell.FlagRemoveFragment|purell.FlagSortQuery)
 	u2, err := url.Parse(urlStr)
 	if err != nil {
-		// We *really* do not expect an error here.
-		panic(err)
+		// Ignore errors here.
+		return nil
 	}
 	return u2
 }
@@ -178,6 +178,13 @@ func (c *Crawler) Enqueue(link Outlink, depth int) error {
 	// Normalize the URL. We are going to replace link.URL in-place, to
 	// ensure that scope checks are applied to the normalized URL.
 	link.URL = normalizeURL(link.URL)
+	if link.URL == nil {
+		// We couldn't parse a URL that we have extracted
+		// ourselves from the documents. This is an internal
+		// inconsistency, but by ignoring the error we avoid
+		// failing the entire crawl.
+		return nil
+	}
 
 	// See if it's in scope.
 	if !c.scope.Check(link, depth) {
diff --git a/go.mod b/go.mod
index 488dbdb9ae77e0717b5425dd555b14374ca5a4e4..5ca4ba4c2661edfea9c7c8334bb0aaac15640a76 100644
--- a/go.mod
+++ b/go.mod
@@ -1,5 +1,7 @@
 module git.autistici.org/ale/crawl
 
+go 1.15
+
 require (
 	github.com/PuerkitoBio/goquery v1.5.0
 	github.com/PuerkitoBio/purell v0.0.0-20180310210909-975f53781597