diff --git a/docs/client-server/specification.rst b/docs/client-server/specification.rst
index 7df2bb14c5..97c8587a6d 100644
--- a/docs/client-server/specification.rst
+++ b/docs/client-server/specification.rst
@@ -262,7 +262,10 @@ the error, but the keys 'error' and 'errcode' will always be present.
Some standard error codes are below:
M_FORBIDDEN:
-Forbidden access, e.g. bad access token, failed login.
+Forbidden access, e.g. joining a room without permission, failed login.
+
+M_UNKNOWN_TOKEN:
+The access token specified was not recognised.
M_BAD_JSON:
Request contained valid JSON, but it was malformed in some way, e.g. missing
diff --git a/synapse/api/auth.py b/synapse/api/auth.py
index 8d2ba242e1..31852b29a5 100644
--- a/synapse/api/auth.py
+++ b/synapse/api/auth.py
@@ -18,7 +18,7 @@
from twisted.internet import defer
from synapse.api.constants import Membership
-from synapse.api.errors import AuthError, StoreError
+from synapse.api.errors import AuthError, StoreError, Codes
from synapse.api.events.room import (RoomTopicEvent, RoomMemberEvent,
MessageEvent, FeedbackEvent)
@@ -163,4 +163,5 @@ class Auth(object):
user_id = yield self.store.get_user_by_token(token=token)
defer.returnValue(self.hs.parse_userid(user_id))
except StoreError:
- raise AuthError(403, "Unrecognised access token.")
+ raise AuthError(403, "Unrecognised access token.",
+ errcode=Codes.UNKNOWN_TOKEN)
diff --git a/synapse/api/errors.py b/synapse/api/errors.py
index b5970c959b..21ededc5ae 100644
--- a/synapse/api/errors.py
+++ b/synapse/api/errors.py
@@ -27,6 +27,7 @@ class Codes(object):
BAD_PAGINATION = "M_BAD_PAGINATION"
UNKNOWN = "M_UNKNOWN"
NOT_FOUND = "M_NOT_FOUND"
+ UNKNOWN_TOKEN = "M_UNKNOWN_TOKEN"
class CodeMessageException(Exception):
|