diff --git a/app/main/errors.py b/app/main/errors.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbd99b13aab12886f6e2faf1e7e718cf79a7da5d
--- /dev/null
+++ b/app/main/errors.py
@@ -0,0 +1,32 @@
+from flask import render_template, request, jsonify
+from . import main
+
+
+@main.app_errorhandler(403)
+def forbidden(e):
+    if request.accept_mimetypes.accept_json and \
+            not request.accept_mimetypes.accept_html:
+        response = jsonify({'error': 'forbidden'})
+        response.status_code = 403
+        return response
+    return render_template('403.html.j2'), 403
+
+
+@main.app_errorhandler(404)
+def page_not_found(e):
+    if request.accept_mimetypes.accept_json and \
+            not request.accept_mimetypes.accept_html:
+        response = jsonify({'error': 'not found'})
+        response.status_code = 404
+        return response
+    return render_template('404.html.j2'), 404
+
+
+@main.app_errorhandler(500)
+def internal_server_error(e):
+    if request.accept_mimetypes.accept_json and \
+            not request.accept_mimetypes.accept_html:
+        response = jsonify({'error': 'internal server error'})
+        response.status_code = 500
+        return response
+    return render_template('500.html.j2'), 500
diff --git a/app/templates/403.html.j2 b/app/templates/403.html.j2
new file mode 100644
index 0000000000000000000000000000000000000000..95c46fda69b832159c60cc1e2074ef3e1258e486
--- /dev/null
+++ b/app/templates/403.html.j2
@@ -0,0 +1,9 @@
+{% extends "base.html.j2" %}
+
+{% block title %}Opaque - Forbidden{% endblock %}
+
+{% block page_content %}
+<div class="page-header">
+    <h1>Forbidden</h1>
+</div>
+{% endblock %}
diff --git a/app/templates/404.html.j2 b/app/templates/404.html.j2
new file mode 100644
index 0000000000000000000000000000000000000000..75f18cd52a781f76d0085bd2a6dda6b9e948ff1b
--- /dev/null
+++ b/app/templates/404.html.j2
@@ -0,0 +1,9 @@
+{% extends "base.html.j2" %}
+
+{% block title %}Opaque - Page Not Found{% endblock %}
+
+{% block page_content %}
+<div class="page-header">
+    <h1>Not Found</h1>
+</div>
+{% endblock %}
diff --git a/app/templates/500.html.j2 b/app/templates/500.html.j2
new file mode 100644
index 0000000000000000000000000000000000000000..43b7a9411a1cf6edbb0f75386ce86e493f621105
--- /dev/null
+++ b/app/templates/500.html.j2
@@ -0,0 +1,9 @@
+{% extends "base.html.j2" %}
+
+{% block title %}Opaque - Internal Server Error{% endblock %}
+
+{% block page_content %}
+<div class="page-header">
+    <h1>Internal Server Error</h1>
+</div>
+{% endblock %}