diff --git a/lib/constants.py b/lib/constants.py
index 51783416c5d03e61cb90162ff9ed00d4427b40a1..a0f1675ac16d042689b07b2fb00f7adcc86f7d06 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -849,6 +849,12 @@ OP_PRIO_LOW = +10
 OP_PRIO_NORMAL = 0
 OP_PRIO_HIGH = -10
 
+OP_PRIO_SUBMIT_VALID = frozenset([
+  OP_PRIO_LOW,
+  OP_PRIO_NORMAL,
+  OP_PRIO_HIGH,
+  ])
+
 OP_PRIO_DEFAULT = OP_PRIO_NORMAL
 
 # Execution log types
diff --git a/lib/jqueue.py b/lib/jqueue.py
index fbcb19675ac1e7d9bd05fba1886f8a280d7714a6..a6c0c7abee3647f3da709a0e78d626fdc88184d6 100644
--- a/lib/jqueue.py
+++ b/lib/jqueue.py
@@ -1370,6 +1370,7 @@ class JobQueue(object):
     @return: the job object to be queued
     @raise errors.JobQueueDrainError: if the job queue is marked for draining
     @raise errors.JobQueueFull: if the job queue has too many jobs in it
+    @raise errors.GenericError: If an opcode is not valid
 
     """
     # Ok when sharing the big job queue lock, as the drain file is created when
@@ -1382,6 +1383,13 @@ class JobQueue(object):
 
     job = _QueuedJob(self, job_id, ops)
 
+    # Check priority
+    for idx, op in enumerate(job.ops):
+      if op.priority not in constants.OP_PRIO_SUBMIT_VALID:
+        allowed = utils.CommaJoin(constants.OP_PRIO_SUBMIT_VALID)
+        raise errors.GenericError("Opcode %s has invalid priority %s, allowed"
+                                  " are %s" % (idx, op.priority, allowed))
+
     # Write to disk
     self.UpdateJobUnlocked(job)