diff --git a/src/test/isolation/README b/src/test/isolation/README
index aeef7f6..2c17876 100644
--- a/src/test/isolation/README
+++ b/src/test/isolation/README
@@ -75,9 +75,11 @@ Support for blocking commands
 
 Each spec may contain commands that block until further action has been taken
 (most likely, some other session runs a step that unblocks it or causes a
-deadlock).  Such a spec needs to be careful to manually specify valid
-permutations, i.e. those that would not expect a blocked session to execute a
-command.  If the spec fails to follow that rule, the spec is aborted.
+deadlock).  In case one permutation is detected to require running a command on
+a session that's blocked by a previous step, this is reported and the
+permutation is aborted; the spec continues with the next permutation.  The spec
+may be careful to specify only permutations that do not cause this problem
+(saving some run time), but this is not a hard requirement.
 
 Only one command can be waiting at a time.  As long as one command is waiting,
 other commands are run to completion synchronously.
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index b1d49c8..6d8b78b 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -50,6 +50,8 @@ static int	step_bsearch_cmp(const void *a, const void *b);
 
 static void printResultSet(PGresult *res);
 
+static void report_invalid_permutation(Step *step);
+
 /* close all connections and exit */
 static void
 exit_nicely(void)
@@ -479,11 +481,38 @@ run_permutation(TestSpec * testspec, int nsteps, Step ** steps)
 	for (i = 0; i < nsteps; i++)
 	{
 		Step *step = steps[i];
+		PGconn *conn = conns[1 + step->session];
+
+		/*
+		 * Found an invalid permutation: one that requires running a command
+		 * on a blocked session.  This can never happen in reality.  Report the
+		 * failure, abort the current permutation, and continue with the next
+		 * permutation.
+		 */
+		if (waiting != NULL && step->session == waiting->session)
+		{
+			int j;
+
+			report_invalid_permutation(step);
+
+			/*
+			 * Finally, complete all running transactions to ensure teardown
+			 * doesn't block.  Note we don't roll back the control connection.
+			 */
+			for (j = 1; j < nconns; j++)
+			{
+				res = PQexec(conns[j], "ROLLBACK");
+				if (res != NULL)
+					PQclear(res);
+			}
 
-		if (!PQsendQuery(conns[1 + step->session], step->sql))
+			goto teardown;
+		}
+
+		if (!PQsendQuery(conn, step->sql))
 		{
 			fprintf(stdout, "failed to send query for step %s: %s\n",
-					step->name, PQerrorMessage(conns[1 + step->session]));
+					step->name, PQerrorMessage(conn));
 			exit_nicely();
 		}
 
@@ -519,6 +548,7 @@ run_permutation(TestSpec * testspec, int nsteps, Step ** steps)
 		report_error_message(waiting);
 	}
 
+teardown:
 	/* Perform per-session teardown */
 	for (i = 0; i < testspec->nsessions; i++)
 	{
@@ -687,3 +717,32 @@ printResultSet(PGresult *res)
 		printf("\n");
 	}
 }
+
+static void
+report_invalid_permutation(Step *step)
+{
+	PGconn *conn = conns[1 + step->session];
+	PGcancel *cancel;
+	PGresult *res;
+
+	fprintf(stdout, "step %s: invalid permutation detected, skipping\n", step->name);
+
+	/* Cancel the waiting statement from this session. */
+	cancel = PQgetCancel(conn);
+	if (cancel)
+	{
+		char buf[256];
+
+		if (PQcancel(cancel, buf, sizeof(buf)) != 1)
+		{
+			fprintf(stdout, "failed to cancel query: %s\n", buf);
+			exit_nicely();
+		}
+
+		/* Be sure to consume whatever is left in the connection */
+		while ((res = PQgetResult(conn)) != NULL)
+			PQclear(res);
+
+		PQfreeCancel(cancel);
+	}
+}
