diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf3d1c968a44c7e3172f4aba94526a463e5e32c5..5f1599870ad351246c069e2e011cd9ae6908f1cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 
 ## [Unreleased]
 
+### Fixed
+
+* Handle guest accounts properly. Previously they were still declined, though by coincidence.
+
 ## [1.2.5] - March 17th, 2021
 
 ### Added
diff --git a/api/auth.go b/api/auth.go
index 2c26bc70977e33205a906b3af797db2d4ca3409c..584f3317f3aef22ff4cd40c3b6ab67d42cc47ba4 100644
--- a/api/auth.go
+++ b/api/auth.go
@@ -39,6 +39,9 @@ func AccessTokenRequiredRoute(next func(r *http.Request, rctx rcontext.RequestCo
 		appserviceUserId := util.GetAppserviceUserIdFromRequest(r)
 		userId, err := auth_cache.GetUserId(rctx, accessToken, appserviceUserId)
 		if err != nil || userId == "" {
+			if err == matrix.ErrGuestToken {
+				return GuestAuthFailed()
+			}
 			if err != nil && err != matrix.ErrInvalidToken {
 				sentry.CaptureException(err)
 				rctx.Log.Error("Error verifying token (fatal): ", err)
diff --git a/api/responses.go b/api/responses.go
index d032ce803b1555bfee26e3d2c5c42059377ba7c7..93d2c39cbf59adcfa907400da85f55247be35794 100644
--- a/api/responses.go
+++ b/api/responses.go
@@ -46,6 +46,10 @@ func AuthFailed() *ErrorResponse {
 	return &ErrorResponse{common.ErrCodeUnknownToken, "Authentication Failed", common.ErrCodeUnknownToken}
 }
 
+func GuestAuthFailed() *ErrorResponse {
+	return &ErrorResponse{common.ErrCodeNoGuests, "Guests cannot use this endpoint", common.ErrCodeNoGuests}
+}
+
 func BadRequest(message string) *ErrorResponse {
 	return &ErrorResponse{common.ErrCodeUnknown, message, common.ErrCodeBadRequest}
 }
diff --git a/common/errorcodes.go b/common/errorcodes.go
index 8deb6494369f3c268535e0f8fe9421ccdda505f2..599b32c95dc4c6d445160c9d2570d7e5b9a28e7b 100644
--- a/common/errorcodes.go
+++ b/common/errorcodes.go
@@ -5,6 +5,7 @@ const ErrCodeHostNotFound = "M_HOST_NOT_FOUND"
 const ErrCodeHostBlacklisted = "M_HOST_BLACKLISTED"
 const ErrCodeNotFound = "M_NOT_FOUND"
 const ErrCodeUnknownToken = "M_UNKNOWN_TOKEN"
+const ErrCodeNoGuests = "M_GUEST_ACCESS_FORBIDDEN"
 const ErrCodeMissingToken = "M_MISSING_TOKEN"
 const ErrCodeMediaTooLarge = "M_MEDIA_TOO_LARGE"
 const ErrCodeMediaTooSmall = "M_MEDIA_TOO_SMALL"
diff --git a/matrix/auth.go b/matrix/auth.go
index 96f0704a53f88e2b3d878445f159441707eaa58d..ca397c8e3629ab7385353fe98c85da2164a7ade9 100644
--- a/matrix/auth.go
+++ b/matrix/auth.go
@@ -10,6 +10,7 @@ import (
 )
 
 var ErrInvalidToken = errors.New("Missing or invalid access token")
+var ErrGuestToken = errors.New("Token belongs to a guest")
 
 func doBreakerRequest(ctx rcontext.RequestContext, serverName string, accessToken string, appserviceUserId string, ipAddr string, method string, path string, resp interface{}) error {
 	if accessToken == "" {
@@ -53,6 +54,9 @@ func GetUserIdFromToken(ctx rcontext.RequestContext, serverName string, accessTo
 	if err != nil {
 		return "", err
 	}
+	if response.IsGuest {
+		return "", ErrGuestToken
+	}
 	return response.UserId, nil
 }
 
diff --git a/matrix/matrix.go b/matrix/matrix.go
index 7a278afdbb6eb43940c9e1ef358341fc288253b6..4abf21d80fb5c3dba13138f08dd80177f5e1e6d9 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -36,9 +36,11 @@ func filterError(err error) (error, error) {
 
 	// Unknown token errors should be filtered out explicitly to ensure we don't break on bad requests
 	if httpErr, ok := err.(*errorResponse); ok {
+		// We send back our own version of errors to ensure we can filter them out elsewhere
 		if httpErr.ErrorCode == common.ErrCodeUnknownToken {
-			// We send back our own version of 'unknown token' to ensure we can filter it out elsewhere
 			return nil, ErrInvalidToken
+		} else if httpErr.ErrorCode == common.ErrCodeNoGuests {
+			return nil, ErrGuestToken
 		}
 	}
 
diff --git a/matrix/responses.go b/matrix/responses.go
index 3efb078b5a60355fa496bb08a0ed979339ee0355..3d93cf213d31186d07b77c7eafb79037be94d831 100644
--- a/matrix/responses.go
+++ b/matrix/responses.go
@@ -8,7 +8,8 @@ type emptyResponse struct {
 }
 
 type userIdResponse struct {
-	UserId string `json:"user_id"`
+	UserId  string `json:"user_id"`
+	IsGuest bool   `json:"org.matrix.msc3069.is_guest"`
 }
 
 type whoisResponse struct {