diff --git a/api/_apimeta/auth.go b/api/_apimeta/auth.go
index 943bbb18ed1059389eefd8b9f30a26cb02536a9b..08874bb544b5bd146854fffc61f8a4aac645c6e7 100644
--- a/api/_apimeta/auth.go
+++ b/api/_apimeta/auth.go
@@ -21,7 +21,7 @@ func GetRequestUserAdminStatus(r *http.Request, rctx rcontext.RequestContext, us
 	isLocalAdmin, err := matrix.IsUserAdmin(rctx, r.Host, user.AccessToken, r.RemoteAddr)
 	if err != nil {
 		sentry.CaptureException(err)
-		rctx.Log.Error("Error verifying local admin: " + err.Error())
+		rctx.Log.Error("Error verifying local admin: ", err)
 		return isGlobalAdmin, false
 	}
 
diff --git a/api/custom/exports.go b/api/custom/exports.go
index 61335e8690a142ca03a0b1f2647cfa43642c2c6f..3a8b17167029de57a4333a136d397afe0843eeb3 100644
--- a/api/custom/exports.go
+++ b/api/custom/exports.go
@@ -99,7 +99,7 @@ func ExportServerData(r *http.Request, rctx rcontext.RequestContext, user _apime
 
 		isLocalAdmin, err := matrix.IsUserAdmin(rctx, serverName, user.AccessToken, r.RemoteAddr)
 		if err != nil {
-			rctx.Log.Error("Error verifying local admin: " + err.Error())
+			rctx.Log.Error("Error verifying local admin: ", err)
 			isLocalAdmin = false
 		}
 		if !isLocalAdmin {
diff --git a/api/custom/purge.go b/api/custom/purge.go
index 703cae8213a7b47945898a042b329a833f6a5212..417055c5743e6b96f2ab78805dcfe7f4c6467b55 100644
--- a/api/custom/purge.go
+++ b/api/custom/purge.go
@@ -41,7 +41,7 @@ func PurgeRemoteMedia(r *http.Request, rctx rcontext.RequestContext, user _apime
 	// We don't bother clearing the cache because it's still probably useful there
 	removed, err := maintenance_controller.PurgeRemoteMediaBefore(beforeTs, rctx)
 	if err != nil {
-		rctx.Log.Error("Error purging remote media: " + err.Error())
+		rctx.Log.Error("Error purging remote media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Error purging remote media")
 	}
@@ -78,7 +78,7 @@ func PurgeIndividualRecord(r *http.Request, rctx rcontext.RequestContext, user _
 				return _responses.NotFoundError()
 			}
 			if err != nil {
-				rctx.Log.Error("Error checking ownership of media: " + err.Error())
+				rctx.Log.Error("Error checking ownership of media: ", err)
 				sentry.CaptureException(err)
 				return _responses.InternalServerError("error checking media ownership")
 			}
@@ -93,7 +93,7 @@ func PurgeIndividualRecord(r *http.Request, rctx rcontext.RequestContext, user _
 		return _responses.NotFoundError()
 	}
 	if err != nil {
-		rctx.Log.Error("Error purging media: " + err.Error())
+		rctx.Log.Error("Error purging media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error purging media")
 	}
@@ -117,7 +117,7 @@ func PurgeQuarantined(r *http.Request, rctx rcontext.RequestContext, user _apime
 	}
 
 	if err != nil {
-		rctx.Log.Error("Error purging media: " + err.Error())
+		rctx.Log.Error("Error purging media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error purging media")
 	}
@@ -158,7 +158,7 @@ func PurgeOldMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta.
 	affected, err := maintenance_controller.PurgeOldMedia(beforeTs, includeLocal, rctx)
 
 	if err != nil {
-		rctx.Log.Error("Error purging media: " + err.Error())
+		rctx.Log.Error("Error purging media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error purging media")
 	}
@@ -196,7 +196,7 @@ func PurgeUserMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta
 
 	_, userDomain, err := util.SplitUserId(userId)
 	if err != nil {
-		rctx.Log.Error("Error parsing user ID (" + userId + "): " + err.Error())
+		rctx.Log.Error("Error parsing user ID ("+userId+"): ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error parsing user ID")
 	}
@@ -208,7 +208,7 @@ func PurgeUserMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta
 	affected, err := maintenance_controller.PurgeUserMedia(userId, beforeTs, rctx)
 
 	if err != nil {
-		rctx.Log.Error("Error purging media: " + err.Error())
+		rctx.Log.Error("Error purging media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error purging media")
 	}
@@ -246,7 +246,7 @@ func PurgeRoomMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta
 
 	allMedia, err := matrix.ListMedia(rctx, r.Host, user.AccessToken, roomId, r.RemoteAddr)
 	if err != nil {
-		rctx.Log.Error("Error while listing media in the room: " + err.Error())
+		rctx.Log.Error("Error while listing media in the room: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error retrieving media in room")
 	}
@@ -286,7 +286,7 @@ func PurgeRoomMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta
 	affected, err := maintenance_controller.PurgeRoomMedia(mxcs, beforeTs, rctx)
 
 	if err != nil {
-		rctx.Log.Error("Error purging media: " + err.Error())
+		rctx.Log.Error("Error purging media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error purging media")
 	}
@@ -333,7 +333,7 @@ func PurgeDomainMedia(r *http.Request, rctx rcontext.RequestContext, user _apime
 	affected, err := maintenance_controller.PurgeDomainMedia(serverName, beforeTs, rctx)
 
 	if err != nil {
-		rctx.Log.Error("Error purging media: " + err.Error())
+		rctx.Log.Error("Error purging media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error purging media")
 	}
diff --git a/api/custom/quarantine.go b/api/custom/quarantine.go
index 4716a1d9b9b39ae076660c835919406653242c00..a016b0ca3aca255cdc6c2001d56ffee7e5e63253 100644
--- a/api/custom/quarantine.go
+++ b/api/custom/quarantine.go
@@ -40,7 +40,7 @@ func QuarantineRoomMedia(r *http.Request, rctx rcontext.RequestContext, user _ap
 
 	allMedia, err := matrix.ListMedia(rctx, r.Host, user.AccessToken, roomId, r.RemoteAddr)
 	if err != nil {
-		rctx.Log.Error("Error while listing media in the room: " + err.Error())
+		rctx.Log.Error("Error while listing media in the room: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error retrieving media in room")
 	}
@@ -53,7 +53,7 @@ func QuarantineRoomMedia(r *http.Request, rctx rcontext.RequestContext, user _ap
 	for _, mxc := range mxcs {
 		server, mediaId, err := util.SplitMxc(mxc)
 		if err != nil {
-			rctx.Log.Error("Error parsing MXC URI (" + mxc + "): " + err.Error())
+			rctx.Log.Error("Error parsing MXC URI ("+mxc+"): ", err)
 			sentry.CaptureException(err)
 			return _responses.InternalServerError("error parsing mxc uri")
 		}
@@ -89,7 +89,7 @@ func QuarantineUserMedia(r *http.Request, rctx rcontext.RequestContext, user _ap
 
 	_, userDomain, err := util.SplitUserId(userId)
 	if err != nil {
-		rctx.Log.Error("Error parsing user ID (" + userId + "): " + err.Error())
+		rctx.Log.Error("Error parsing user ID ("+userId+"): ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error parsing user ID")
 	}
@@ -101,7 +101,7 @@ func QuarantineUserMedia(r *http.Request, rctx rcontext.RequestContext, user _ap
 	db := storage.GetDatabase().GetMediaStore(rctx)
 	userMedia, err := db.GetMediaByUser(userId)
 	if err != nil {
-		rctx.Log.Error("Error while listing media for the user: " + err.Error())
+		rctx.Log.Error("Error while listing media for the user: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error retrieving media for user")
 	}
@@ -143,7 +143,7 @@ func QuarantineDomainMedia(r *http.Request, rctx rcontext.RequestContext, user _
 	db := storage.GetDatabase().GetMediaStore(rctx)
 	userMedia, err := db.GetAllMediaForServer(serverName)
 	if err != nil {
-		rctx.Log.Error("Error while listing media for the server: " + err.Error())
+		rctx.Log.Error("Error while listing media for the server: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error retrieving media for server")
 	}
@@ -197,7 +197,7 @@ func doQuarantine(ctx rcontext.RequestContext, origin string, mediaId string, al
 			return &MediaQuarantinedResponse{0}, true
 		}
 
-		ctx.Log.Error("Error fetching media: " + err.Error())
+		ctx.Log.Error("Error fetching media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("error quarantining media"), false
 	}
@@ -210,7 +210,7 @@ func doQuarantineOn(media *types.Media, allowOtherHosts bool, ctx rcontext.Reque
 	attrDb := storage.GetDatabase().GetMediaAttributesStore(ctx)
 	attr, err := attrDb.GetAttributesDefaulted(media.Origin, media.MediaId)
 	if err != nil {
-		ctx.Log.Error("Error while getting attributes for media: " + err.Error())
+		ctx.Log.Error("Error while getting attributes for media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Error quarantining media"), false
 	}
@@ -225,7 +225,7 @@ func doQuarantineOn(media *types.Media, allowOtherHosts bool, ctx rcontext.Reque
 
 	num, err := setMediaQuarantined(media, true, allowOtherHosts, ctx)
 	if err != nil {
-		ctx.Log.Error("Error quarantining media: " + err.Error())
+		ctx.Log.Error("Error quarantining media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Error quarantining media"), false
 	}
@@ -271,7 +271,7 @@ func getQuarantineRequestInfo(r *http.Request, rctx rcontext.RequestContext, use
 			isLocalAdmin, err = matrix.IsUserAdmin(rctx, r.Host, user.AccessToken, r.RemoteAddr)
 			if err != nil {
 				sentry.CaptureException(err)
-				rctx.Log.Error("Error verifying local admin: " + err.Error())
+				rctx.Log.Error("Error verifying local admin: ", err)
 				canQuarantine = false
 				return canQuarantine, allowOtherHosts, isLocalAdmin
 			}
diff --git a/api/r0/download.go b/api/r0/download.go
index 5ecf793aa99454767b1ba202049bc9942fb68043..af4a23e158cd49e6ab89194e0b3f002148feab42 100644
--- a/api/r0/download.go
+++ b/api/r0/download.go
@@ -83,7 +83,7 @@ func DownloadMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta.
 		} else if err == common.ErrMediaNotYetUploaded {
 			return _responses.NotYetUploaded()
 		}
-		rctx.Log.Error("Unexpected error locating media: " + err.Error())
+		rctx.Log.Error("Unexpected error locating media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
diff --git a/api/r0/preview_url.go b/api/r0/preview_url.go
index 2f42a291246ddb3ff92aa7a46f96b07b5941e79d..30b52d93ff1476879057c04fdb967ca50cd2914e 100644
--- a/api/r0/preview_url.go
+++ b/api/r0/preview_url.go
@@ -44,7 +44,7 @@ func PreviewUrl(r *http.Request, rctx rcontext.RequestContext, user _apimeta.Use
 	if tsStr != "" {
 		ts, err = strconv.ParseInt(tsStr, 10, 64)
 		if err != nil {
-			rctx.Log.Error("Error parsing ts: " + err.Error())
+			rctx.Log.Error("Error parsing ts: ", err)
 			return _responses.BadRequest(err.Error())
 		}
 	}
diff --git a/api/r0/thumbnail.go b/api/r0/thumbnail.go
index a98a292dbfd1c0a346ff7cb3095aed45fa82b353..eee357cc7785347ee00f61b7ecec81bdc0c7be7e 100644
--- a/api/r0/thumbnail.go
+++ b/api/r0/thumbnail.go
@@ -132,7 +132,7 @@ func ThumbnailMedia(r *http.Request, rctx rcontext.RequestContext, user _apimeta
 		} else if err == common.ErrMediaNotYetUploaded {
 			return _responses.NotYetUploaded()
 		}
-		rctx.Log.Error("Unexpected error locating media: " + err.Error())
+		rctx.Log.Error("Unexpected error locating media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
diff --git a/api/r0/upload_async.go b/api/r0/upload_async.go
index 05f905844a5dae70e70402e6b155c97e7ad12740..8d0bd6f31f967568177bf1c92422ad6154d61f3c 100644
--- a/api/r0/upload_async.go
+++ b/api/r0/upload_async.go
@@ -68,14 +68,14 @@ func UploadMediaAsync(r *http.Request, rctx rcontext.RequestContext, user _apime
 				InternalCode: common.ErrCodeNotFound,
 			}
 		}
-		rctx.Log.Error("Unexpected error uploading media: " + err.Error())
+		rctx.Log.Error("Unexpected error uploading media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
 
 	blurhash, err := database.GetInstance().Blurhashes.Prepare(rctx).Get(media.Sha256Hash)
 	if err != nil {
-		rctx.Log.Warn("Unexpected error getting media's blurhash from DB: " + err.Error())
+		rctx.Log.Warn("Unexpected error getting media's blurhash from DB: ", err)
 		sentry.CaptureException(err)
 	}
 
diff --git a/api/r0/upload_sync.go b/api/r0/upload_sync.go
index 1e1ab87121e5dfcee18b6357ca0c8f5d401e6f73..b8cb7f326436a7b16ee9e9511f496d1d18d84c8d 100644
--- a/api/r0/upload_sync.go
+++ b/api/r0/upload_sync.go
@@ -45,14 +45,14 @@ func UploadMediaSync(r *http.Request, rctx rcontext.RequestContext, user _apimet
 		if err == common.ErrQuotaExceeded {
 			return _responses.QuotaExceeded()
 		}
-		rctx.Log.Error("Unexpected error uploading media: " + err.Error())
+		rctx.Log.Error("Unexpected error uploading media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
 
 	blurhash, err := database.GetInstance().Blurhashes.Prepare(rctx).Get(media.Sha256Hash)
 	if err != nil {
-		rctx.Log.Warn("Unexpected error getting media's blurhash from DB: " + err.Error())
+		rctx.Log.Warn("Unexpected error getting media's blurhash from DB: ", err)
 		sentry.CaptureException(err)
 	}
 
diff --git a/api/unstable/info.go b/api/unstable/info.go
index 02a816a2229ea64adfae01921959c1cca0a8f16b..d153cee0e4150dfe25235a0e3d1d39ac6756b227 100644
--- a/api/unstable/info.go
+++ b/api/unstable/info.go
@@ -88,7 +88,7 @@ func MediaInfo(r *http.Request, rctx rcontext.RequestContext, user _apimeta.User
 		} else if err == common.ErrMediaQuarantined {
 			return _responses.NotFoundError() // We lie for security
 		}
-		rctx.Log.Error("Unexpected error locating media: " + err.Error())
+		rctx.Log.Error("Unexpected error locating media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
@@ -96,7 +96,7 @@ func MediaInfo(r *http.Request, rctx rcontext.RequestContext, user _apimeta.User
 
 	b, err := io.ReadAll(streamedMedia.Stream)
 	if err != nil {
-		rctx.Log.Error("Unexpected error processing media: " + err.Error())
+		rctx.Log.Error("Unexpected error processing media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
@@ -119,7 +119,7 @@ func MediaInfo(r *http.Request, rctx rcontext.RequestContext, user _apimeta.User
 	thumbsDb := storage.GetDatabase().GetThumbnailStore(rctx)
 	thumbs, err := thumbsDb.GetAllForMedia(streamedMedia.KnownMedia.Origin, streamedMedia.KnownMedia.MediaId)
 	if err != nil && err != sql.ErrNoRows {
-		rctx.Log.Error("Unexpected error locating media: " + err.Error())
+		rctx.Log.Error("Unexpected error locating media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
diff --git a/api/unstable/local_copy.go b/api/unstable/local_copy.go
index fa5a1f03d8b383332ab8e6547e4280e8e765e38e..3c654c04b2d5f822defb042e4a6433f24ae82307 100644
--- a/api/unstable/local_copy.go
+++ b/api/unstable/local_copy.go
@@ -59,7 +59,7 @@ func LocalCopy(r *http.Request, rctx rcontext.RequestContext, user _apimeta.User
 		} else if err == common.ErrMediaQuarantined {
 			return _responses.NotFoundError() // We lie for security
 		}
-		rctx.Log.Error("Unexpected error locating media: " + err.Error())
+		rctx.Log.Error("Unexpected error locating media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
@@ -72,7 +72,7 @@ func LocalCopy(r *http.Request, rctx rcontext.RequestContext, user _apimeta.User
 
 	newMedia, err := upload_controller.UploadMedia(streamedMedia.Stream, streamedMedia.KnownMedia.SizeBytes, streamedMedia.KnownMedia.ContentType, streamedMedia.KnownMedia.UploadName, user.UserId, r.Host, rctx)
 	if err != nil {
-		rctx.Log.Error("Unexpected error storing media: " + err.Error())
+		rctx.Log.Error("Unexpected error storing media: ", err)
 		sentry.CaptureException(err)
 		return _responses.InternalServerError("Unexpected Error")
 	}
diff --git a/controllers/maintenance_controller/maintainance_controller.go b/controllers/maintenance_controller/maintainance_controller.go
index 1df60a32d194f7fb6950c6556d1d175d5c9c3715..23424f7342342d66c497ed5e8728c1b3b0d9e139 100644
--- a/controllers/maintenance_controller/maintainance_controller.go
+++ b/controllers/maintenance_controller/maintainance_controller.go
@@ -3,9 +3,10 @@ package maintenance_controller
 import (
 	"database/sql"
 	"fmt"
-	"github.com/getsentry/sentry-go"
 	"os"
 
+	"github.com/getsentry/sentry-go"
+
 	"github.com/sirupsen/logrus"
 	"github.com/turt2live/matrix-media-repo/common/rcontext"
 	"github.com/turt2live/matrix-media-repo/controllers/download_controller"
@@ -194,7 +195,7 @@ func PurgeRemoteMediaBefore(beforeTs int64, ctx rcontext.RequestContext) (int, e
 
 		ds, err := datastore.LocateDatastore(ctx, media.DatastoreId)
 		if err != nil {
-			ctx.Log.Error("Error finding datastore for media " + media.Origin + "/" + media.MediaId + " because: " + err.Error())
+			ctx.Log.Error("Error finding datastore for media "+media.Origin+"/"+media.MediaId+" because: ", err)
 			sentry.CaptureException(err)
 			continue
 		}
@@ -202,7 +203,7 @@ func PurgeRemoteMediaBefore(beforeTs int64, ctx rcontext.RequestContext) (int, e
 		// Delete the file first
 		err = ds.DeleteObject(media.Location)
 		if err != nil {
-			ctx.Log.Warn("Cannot remove media " + media.Origin + "/" + media.MediaId + " because: " + err.Error())
+			ctx.Log.Warn("Cannot remove media "+media.Origin+"/"+media.MediaId+" because: ", err)
 			sentry.CaptureException(err)
 		} else {
 			removed++
@@ -212,14 +213,14 @@ func PurgeRemoteMediaBefore(beforeTs int64, ctx rcontext.RequestContext) (int, e
 		// Try to remove the record from the database now
 		err = db.Delete(media.Origin, media.MediaId)
 		if err != nil {
-			ctx.Log.Warn("Error removing media " + media.Origin + "/" + media.MediaId + " from database: " + err.Error())
+			ctx.Log.Warn("Error removing media "+media.Origin+"/"+media.MediaId+" from database: ", err)
 			sentry.CaptureException(err)
 		}
 
 		// Delete the thumbnails too
 		thumbs, err := thumbsDb.GetAllForMedia(media.Origin, media.MediaId)
 		if err != nil {
-			ctx.Log.Warn("Error getting thumbnails for media " + media.Origin + "/" + media.MediaId + " from database: " + err.Error())
+			ctx.Log.Warn("Error getting thumbnails for media "+media.Origin+"/"+media.MediaId+" from database: ", err)
 			sentry.CaptureException(err)
 			continue
 		}
@@ -227,21 +228,21 @@ func PurgeRemoteMediaBefore(beforeTs int64, ctx rcontext.RequestContext) (int, e
 			ctx.Log.Info("Deleting thumbnail with hash: ", thumb.Sha256Hash)
 			ds, err := datastore.LocateDatastore(ctx, thumb.DatastoreId)
 			if err != nil {
-				ctx.Log.Warn("Error removing thumbnail for media " + media.Origin + "/" + media.MediaId + " from database: " + err.Error())
+				ctx.Log.Warn("Error removing thumbnail for media "+media.Origin+"/"+media.MediaId+" from database: ", err)
 				sentry.CaptureException(err)
 				continue
 			}
 
 			err = ds.DeleteObject(thumb.Location)
 			if err != nil {
-				ctx.Log.Warn("Error removing thumbnail for media " + media.Origin + "/" + media.MediaId + " from database: " + err.Error())
+				ctx.Log.Warn("Error removing thumbnail for media "+media.Origin+"/"+media.MediaId+" from database: ", err)
 				sentry.CaptureException(err)
 				continue
 			}
 		}
 		err = thumbsDb.DeleteAllForMedia(media.Origin, media.MediaId)
 		if err != nil {
-			ctx.Log.Warn("Error removing thumbnails for media " + media.Origin + "/" + media.MediaId + " from database: " + err.Error())
+			ctx.Log.Warn("Error removing thumbnails for media "+media.Origin+"/"+media.MediaId+" from database: ", err)
 			sentry.CaptureException(err)
 		}
 	}
diff --git a/controllers/preview_controller/preview_resource_handler.go b/controllers/preview_controller/preview_resource_handler.go
index 119df0d80ff2d68843a2caa5cca06c751111491c..b45dfd03eeaadafb491a7d70c94953872fbc9ff6 100644
--- a/controllers/preview_controller/preview_resource_handler.go
+++ b/controllers/preview_controller/preview_resource_handler.go
@@ -135,18 +135,18 @@ func urlPreviewWorkFn(request *resource_handler.WorkRequest) (resp *urlPreviewRe
 		// UploadMedia will close the read stream for the thumbnail and dedupe the image
 		media, err := upload_controller.UploadMedia(preview.Image.Data, contentLength, preview.Image.ContentType, preview.Image.Filename, info.forUserId, info.onHost, ctx)
 		if err != nil {
-			ctx.Log.Warn("Non-fatal error storing preview thumbnail: " + err.Error())
+			ctx.Log.Warn("Non-fatal error storing preview thumbnail: ", err)
 			sentry.CaptureException(err)
 		} else {
 			mediaStream, err := datastore.DownloadStream(ctx, media.DatastoreId, media.Location)
 			if err != nil {
-				ctx.Log.Warn("Non-fatal error streaming datastore file: " + err.Error())
+				ctx.Log.Warn("Non-fatal error streaming datastore file: ", err)
 				sentry.CaptureException(err)
 			} else {
 				defer stream_util.DumpAndCloseStream(mediaStream)
 				img, err := imaging.Decode(mediaStream)
 				if err != nil {
-					ctx.Log.Warn("Non-fatal error getting thumbnail dimensions: " + err.Error())
+					ctx.Log.Warn("Non-fatal error getting thumbnail dimensions: ", err)
 					sentry.CaptureException(err)
 				} else {
 					result.ImageMxc = media.MxcUri()
@@ -167,7 +167,7 @@ func urlPreviewWorkFn(request *resource_handler.WorkRequest) (resp *urlPreviewRe
 	}
 	err = db.InsertPreview(dbRecord)
 	if err != nil {
-		ctx.Log.Warn("Error caching URL preview: " + err.Error())
+		ctx.Log.Warn("Error caching URL preview: ", err)
 		sentry.CaptureException(err)
 		// Non-fatal: Just report it and move on. The worst that happens is we re-cache it.
 	}
diff --git a/controllers/upload_controller/upload_controller.go b/controllers/upload_controller/upload_controller.go
index 69eec8ff0cbe6bf04f5f043463dfed222f16b3c9..15e912b7853c31afa06421e1615b3c6ea79a5397 100644
--- a/controllers/upload_controller/upload_controller.go
+++ b/controllers/upload_controller/upload_controller.go
@@ -145,7 +145,7 @@ func UploadMedia(contents io.ReadCloser, contentLength int64, contentType string
 	if m != nil {
 		err = internal_cache.Get().UploadMedia(m.Sha256Hash, util_byte_seeker.NewByteSeeker(dataBytes), ctx)
 		if err != nil {
-			ctx.Log.Warn("Unexpected error trying to cache media: " + err.Error())
+			ctx.Log.Warn("Unexpected error trying to cache media: ", err)
 		}
 	}
 	return m, err
diff --git a/pipelines/_steps/upload/lock.go b/pipelines/_steps/upload/lock.go
index 83fdaf24d428e9a02bb922d6fd13bd89c8e62e8b..b6f87c03ea8d9f0a38c374d57cc23503a10c2746 100644
--- a/pipelines/_steps/upload/lock.go
+++ b/pipelines/_steps/upload/lock.go
@@ -24,7 +24,7 @@ func LockForUpload(ctx rcontext.RequestContext, hash string) (func() error, erro
 				if time.Now().After(attemptDoneAt) {
 					return nil, errors.New("failed to acquire upload lock: " + err.Error())
 				} else {
-					ctx.Log.Warn("failed to acquire upload lock: " + err.Error())
+					ctx.Log.Warn("failed to acquire upload lock: ", err)
 				}
 			} else {
 				acquired = true
diff --git a/storage/datastore/ds_file/file_store.go b/storage/datastore/ds_file/file_store.go
index fa5870102e642ccfc8bf7e8c8ddf290022b6ca96..182d2349ecd7c25534d26fb8057459ae2bcf7ee1 100644
--- a/storage/datastore/ds_file/file_store.go
+++ b/storage/datastore/ds_file/file_store.go
@@ -42,7 +42,7 @@ func PersistFile(basePath string, file io.ReadCloser, ctx rcontext.RequestContex
 		attempts++
 
 		if err != nil {
-			ctx.Log.Error("Error checking if the file exists: " + err.Error())
+			ctx.Log.Error("Error checking if the file exists: ", err)
 		}
 
 		// Infinite loop protection
diff --git a/url_previewers/calculated_previewer.go b/url_previewers/calculated_previewer.go
index 9df34458efdf57d746020aebca8f0ee0932a6e8f..753ca943d329958a3b2a9c3cca2cccbaa00d9441 100644
--- a/url_previewers/calculated_previewer.go
+++ b/url_previewers/calculated_previewer.go
@@ -14,7 +14,7 @@ import (
 func GenerateCalculatedPreview(urlPayload *UrlPayload, languageHeader string, ctx rcontext.RequestContext) (PreviewResult, error) {
 	bytes, filename, contentType, contentLength, err := downloadRawContent(urlPayload, ctx.Config.UrlPreviews.FilePreviewTypes, languageHeader, ctx)
 	if err != nil {
-		ctx.Log.Error("Error downloading content: " + err.Error())
+		ctx.Log.Error("Error downloading content: ", err)
 
 		// Make sure the unsupported error gets passed through
 		if err == ErrPreviewUnsupported {
diff --git a/url_previewers/oembed_previewer.go b/url_previewers/oembed_previewer.go
index 1658ed4de4a85ed1b7cf34f43a6e249afa54a9de..8a86c2e29e55fc0b2aa1770f29cebf8b397be0d1 100644
--- a/url_previewers/oembed_previewer.go
+++ b/url_previewers/oembed_previewer.go
@@ -52,7 +52,7 @@ func GenerateOEmbedPreview(urlPayload *UrlPayload, languageHeader string, ctx rc
 		AcceptLanguage: languageHeader,
 	})
 	if err != nil {
-		ctx.Log.Error("Error getting oEmbed: " + err.Error())
+		ctx.Log.Error("Error getting oEmbed: ", err)
 		return PreviewResult{}, err
 	}
 
@@ -73,7 +73,7 @@ func GenerateOEmbedPreview(urlPayload *UrlPayload, languageHeader string, ctx rc
 	if info.ThumbnailURL != "" {
 		imgUrl, err := url.Parse(info.ThumbnailURL)
 		if err != nil {
-			ctx.Log.Error("Non-fatal error getting thumbnail (parsing image url): " + err.Error())
+			ctx.Log.Error("Non-fatal error getting thumbnail (parsing image url): ", err)
 			sentry.CaptureException(err)
 			return *graph, nil
 		}
@@ -86,7 +86,7 @@ func GenerateOEmbedPreview(urlPayload *UrlPayload, languageHeader string, ctx rc
 
 		img, err := downloadImage(imgUrlPayload, languageHeader, ctx)
 		if err != nil {
-			ctx.Log.Error("Non-fatal error getting thumbnail (downloading image): " + err.Error())
+			ctx.Log.Error("Non-fatal error getting thumbnail (downloading image): ", err)
 			sentry.CaptureException(err)
 			return *graph, nil
 		}
diff --git a/url_previewers/opengraph_previewer.go b/url_previewers/opengraph_previewer.go
index 878a70399ae08d1cde7463866d3f8fc6aa493be2..e4e62e6029c161c1618307bb43a8cdfec0dfcbed 100644
--- a/url_previewers/opengraph_previewer.go
+++ b/url_previewers/opengraph_previewer.go
@@ -21,7 +21,7 @@ var ogSupportedTypes = []string{"text/*"}
 func GenerateOpenGraphPreview(urlPayload *UrlPayload, languageHeader string, ctx rcontext.RequestContext) (PreviewResult, error) {
 	html, err := downloadHtmlContent(urlPayload, ogSupportedTypes, languageHeader, ctx)
 	if err != nil {
-		ctx.Log.Error("Error downloading content: " + err.Error())
+		ctx.Log.Error("Error downloading content: ", err)
 
 		// Make sure the unsupported error gets passed through
 		if err == ErrPreviewUnsupported {
@@ -35,7 +35,7 @@ func GenerateOpenGraphPreview(urlPayload *UrlPayload, languageHeader string, ctx
 	og := opengraph.NewOpenGraph()
 	err = og.ProcessHTML(strings.NewReader(html))
 	if err != nil {
-		ctx.Log.Error("Error getting OpenGraph: " + err.Error())
+		ctx.Log.Error("Error getting OpenGraph: ", err)
 		return PreviewResult{}, err
 	}
 
@@ -64,7 +64,7 @@ func GenerateOpenGraphPreview(urlPayload *UrlPayload, languageHeader string, ctx
 	if og.Images != nil && len(og.Images) > 0 {
 		imgUrl, err := url.Parse(og.Images[0].URL)
 		if err != nil {
-			ctx.Log.Error("Non-fatal error getting thumbnail (parsing image url): " + err.Error())
+			ctx.Log.Error("Non-fatal error getting thumbnail (parsing image url): ", err)
 			sentry.CaptureException(err)
 			return *graph, nil
 		}
@@ -77,7 +77,7 @@ func GenerateOpenGraphPreview(urlPayload *UrlPayload, languageHeader string, ctx
 
 		img, err := downloadImage(imgUrlPayload, languageHeader, ctx)
 		if err != nil {
-			ctx.Log.Error("Non-fatal error getting thumbnail (downloading image): " + err.Error())
+			ctx.Log.Error("Non-fatal error getting thumbnail (downloading image): ", err)
 			sentry.CaptureException(err)
 			return *graph, nil
 		}