diff --git a/fe/http.go b/fe/http.go
index 45ff06992fe5bf02fd72c17cc4c12184de484e33..9fbf4fccf822d76e07078f4632db3949b0b9a114 100644
--- a/fe/http.go
+++ b/fe/http.go
@@ -120,19 +120,25 @@ func (h *HttpRedirector) serveRelay(mount *autoradio.Mount, w http.ResponseWrite
 	}
 	httpTargetStats.IncrVar(ipToMetric(relayAddr))
 
-	// Create the m3u response.
-	m3u := fmt.Sprintf("%s\n", makeIcecastUrl(relayAddr, mount.Name))
-	w.Header().Set("Content-Length", strconv.Itoa(len(m3u)))
-	w.Header().Set("Content-Type", "audio/x-mpegurl")
-	addDefaultHeaders(w)
-	io.WriteString(w, m3u)
+	targetURL := makeIcecastUrl(relayAddr, mount.Name)
+
+	// See if we need to serve a M3U response or a redirect.
+	if strings.HasSuffix(r.URL.Path, ".m3u") {
+		m3u := targetURL + "\n"
+		w.Header().Set("Content-Length", strconv.Itoa(len(m3u)))
+		w.Header().Set("Content-Type", "audio/x-mpegurl")
+		addDefaultHeaders(w)
+		io.WriteString(w, m3u)
+	} else {
+		http.Redirect(w, r, targetURL, 302)
+	}
 }
 
 // Handle SOURCE requests.
 func (h *HttpRedirector) serveSource(mount *autoradio.Mount, w http.ResponseWriter, r *http.Request) {
 	if mount.IsRelay() {
 		log.Printf("source: connection to relay stream %s", mount.Name)
-		http.Error(w, "Source Connection To Relay Stream", http.StatusBadRequest)
+		http.Error(w, "Stream is relayed", http.StatusBadRequest)
 		source404Errors.Incr()
 		return
 	}