diff --git a/util/http.py b/util/http.py
index 05f27970e..16cc517c3 100644
--- a/util/http.py
+++ b/util/http.py
@@ -1,5 +1,6 @@
 import logging
 
+from app import mixpanel
 from flask import request, abort as flask_abort, make_response
 from auth.auth import process_auth, extract_namespace_repo_from_session, get_authenticated_user, get_validated_token
 
@@ -15,16 +16,21 @@ DEFAULT_MESSAGE[409] = 'Conflict'
 def abort(status_code, message=None, **kwargs):
   message = str(message) % kwargs if message else DEFAULT_MESSAGE.get(status_code, '')
 
+  params = dict(request.view_args)
+  params.copy(kwargs)
+
   # Add the user information.
   auth_user = get_authenticated_user()
   auth_token = get_validated_token()
   if auth_user:
+    mixpanel.track(auth_user.username, 'http_error', params)
     message = '%s (user: %s)' % (message, auth_user.username)
   elif auth_token:
+    mixpanel.track(auth_token.core, 'http_error', params)
     message = '%s (token: %s)' % (message, auth_token.friendly_name or auth_token.code)
 
   # Log the abort.
-  logger.error('Error %s: %s. Arguments: %s' % (status_code, message, request.view_args))
+  logger.error('Error %s: %s. Arguments: %s' % (status_code, message, params))
 
   # Report the abort to the user.
   flask_abort(make_response(message, status_code, {}))