diff --git a/server/subsonic/api.go b/server/subsonic/api.go
index 1d1ee61ae..30b4d2816 100644
--- a/server/subsonic/api.go
+++ b/server/subsonic/api.go
@@ -171,7 +171,11 @@ func h(r chi.Router, path string, f handler) {
 		if err != nil {
 			// If it is not a Subsonic error, convert it to an ErrorGeneric
 			if _, ok := err.(subError); !ok {
-				err = newError(responses.ErrorGeneric, "Internal Error")
+				if err == model.ErrNotFound {
+					err = newError(responses.ErrorDataNotFound, "data not found")
+				} else {
+					err = newError(responses.ErrorGeneric, "Internal Error")
+				}
 			}
 			sendError(w, r, err)
 			return
diff --git a/server/subsonic/media_retrieval.go b/server/subsonic/media_retrieval.go
index 8db8a3b10..db928ca02 100644
--- a/server/subsonic/media_retrieval.go
+++ b/server/subsonic/media_retrieval.go
@@ -4,8 +4,10 @@ import (
 	"io"
 	"net/http"
 
+	"github.com/deluan/navidrome/conf"
 	"github.com/deluan/navidrome/consts"
 	"github.com/deluan/navidrome/core"
+	"github.com/deluan/navidrome/core/gravatar"
 	"github.com/deluan/navidrome/log"
 	"github.com/deluan/navidrome/model"
 	"github.com/deluan/navidrome/resources"
@@ -15,13 +17,35 @@ import (
 
 type MediaRetrievalController struct {
 	artwork core.Artwork
+	ds      model.DataStore
 }
 
-func NewMediaRetrievalController(artwork core.Artwork) *MediaRetrievalController {
-	return &MediaRetrievalController{artwork: artwork}
+func NewMediaRetrievalController(artwork core.Artwork, ds model.DataStore) *MediaRetrievalController {
+	return &MediaRetrievalController{artwork: artwork, ds: ds}
 }
 
 func (c *MediaRetrievalController) GetAvatar(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
+	if !conf.Server.EnableGravatar {
+		return c.getPlaceHolderAvatar(w, r)
+	}
+	username, err := requiredParamString(r, "username")
+	if err != nil {
+		return nil, err
+	}
+	ctx := r.Context()
+	u, err := c.ds.User(ctx).FindByUsername(username)
+	if err != nil {
+		return nil, err
+	}
+	if u.Email == "" {
+		log.Warn(ctx, "User needs an email for gravatar to work", "username", username)
+		return c.getPlaceHolderAvatar(w, r)
+	}
+	http.Redirect(w, r, gravatar.Url(u.Email, 0), http.StatusFound)
+	return nil, nil
+}
+
+func (c *MediaRetrievalController) getPlaceHolderAvatar(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
 	f, err := resources.AssetFile().Open(consts.PlaceholderAvatar)
 	if err != nil {
 		log.Error(r, "Image not found", err)
diff --git a/server/subsonic/media_retrieval_test.go b/server/subsonic/media_retrieval_test.go
index 78513ec7c..dc2e6b00a 100644
--- a/server/subsonic/media_retrieval_test.go
+++ b/server/subsonic/media_retrieval_test.go
@@ -7,6 +7,7 @@ import (
 	"net/http/httptest"
 
 	"github.com/deluan/navidrome/model"
+	"github.com/deluan/navidrome/tests"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 )
@@ -18,7 +19,7 @@ var _ = Describe("MediaRetrievalController", func() {
 
 	BeforeEach(func() {
 		artwork = &fakeArtwork{}
-		controller = NewMediaRetrievalController(artwork)
+		controller = NewMediaRetrievalController(artwork, &tests.MockDataStore{})
 		w = httptest.NewRecorder()
 	})
 
diff --git a/server/subsonic/wire_gen.go b/server/subsonic/wire_gen.go
index dd7f3d24a..c4f28a586 100644
--- a/server/subsonic/wire_gen.go
+++ b/server/subsonic/wire_gen.go
@@ -57,7 +57,8 @@ func initUsersController(router *Router) *UsersController {
 
 func initMediaRetrievalController(router *Router) *MediaRetrievalController {
 	artwork := router.Artwork
-	mediaRetrievalController := NewMediaRetrievalController(artwork)
+	dataStore := router.DataStore
+	mediaRetrievalController := NewMediaRetrievalController(artwork, dataStore)
 	return mediaRetrievalController
 }