diff --git a/helios/templates/voters_list.html b/helios/templates/voters_list.html
index d79689520ba79c9b0fb2157351adaff7f13f1528..aa4a5ef5bfa623b8f69c2833b12e7ffdb11f06ee 100644
--- a/helios/templates/voters_list.html
+++ b/helios/templates/voters_list.html
@@ -30,7 +30,7 @@
 <br />
 {% if admin_p and upload_p %}
 <p>
-{% if not election.frozen_at %}
+{% if election.openreg or not election.frozen_at %}
 <a href="{% url helios.views.voters_upload election_uuid=election.uuid %}">bulk upload voters</a>
 {% endif %}
 </p>
diff --git a/helios/views.py b/helios/views.py
index 65896c59b01aabb122f038cdd4d4446c3b303202..71771f8e3519dd8051d4c4013529c1ef67d7ece1 100644
--- a/helios/views.py
+++ b/helios/views.py
@@ -879,7 +879,7 @@ def voters_list_pretty(request, election):
                                                   'upload_p': helios.VOTERS_UPLOAD, 'q' : q,
                                                   'voter_files': voter_files})
 
-@election_admin(frozen=False)
+@election_admin()
 def voters_upload(request, election):
   """
   Upload a CSV of password-based voters with
@@ -887,6 +887,9 @@ def voters_upload(request, election):
   
   name and email are needed only if voter_type is static
   """
+  if election.frozen_at and not election.openreg:
+    raise PermissionDenied()
+
   if request.method == "GET":
     return render_template(request, 'voters_upload', {'election': election})