diff --git a/pressure-vessel/launcher.c b/pressure-vessel/launcher.c
index 4cd95695559ab7d711f6cef2e3df9f20d12ddc72..252d5d5a4e3a3a44819932ae411e588f9fe60997 100644
--- a/pressure-vessel/launcher.c
+++ b/pressure-vessel/launcher.c
@@ -1096,7 +1096,6 @@ main (int argc,
   guint exit_on_readable_id = 0;
   g_autoptr(GError) local_error = NULL;
   GError **error = &local_error;
-  gsize i;
   int ret = EX_USAGE;
 
   my_pid = getpid ();
@@ -1210,35 +1209,12 @@ main (int argc,
 
   client_pid_data_hash = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) pid_data_free);
 
-  /* --socket argument needs to be printable so we can print
-   * "socket=%s\n" without escaping */
-  if (opt_socket != NULL)
-    {
-      for (i = 0; opt_socket[i] != '\0'; i++)
-        {
-          if (!g_ascii_isprint (opt_socket[i]))
-            {
-              glnx_throw (error,
-                          "Non-printable characters not allowed in --socket");
-              goto out;
-            }
-        }
-    }
-
-  /* --socket-directory argument likewise */
-  if (opt_socket_directory != NULL)
-    {
-      for (i = 0; opt_socket_directory[i] != '\0'; i++)
-        {
-          if (!g_ascii_isprint (opt_socket_directory[i]))
-            {
-              glnx_throw (error,
-                          "Non-printable characters not allowed in "
-                          "--socket-directory");
-              goto out;
-            }
-        }
-    }
+  if (!pv_portal_listener_check_socket_arguments (global_listener,
+                                                  opt_bus_name,
+                                                  opt_socket,
+                                                  opt_socket_directory,
+                                                  error))
+    goto out;
 
   /* Exit with this status until we know otherwise */
   ret = EX_SOFTWARE;
@@ -1247,15 +1223,6 @@ main (int argc,
     {
       GBusNameOwnerFlags flags;
 
-      if (opt_socket != NULL || opt_socket_directory != NULL)
-        {
-          glnx_throw (error,
-                      "--bus-name cannot be combined with --socket or "
-                      "--socket-directory");
-          ret = EX_USAGE;
-          goto out;
-        }
-
       g_debug ("Connecting to D-Bus session bus...");
 
       session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
@@ -1283,14 +1250,6 @@ main (int argc,
     }
   else if (opt_socket != NULL)
     {
-      if (opt_socket_directory != NULL)
-        {
-          glnx_throw (error,
-                      "--socket and --socket-directory cannot both be used");
-          ret = EX_USAGE;
-          goto out;
-        }
-
       g_debug ("Listening on socket %s...", opt_socket);
       server = listen_on_socket (opt_socket, error);
 
@@ -1349,10 +1308,8 @@ main (int argc,
     }
   else
     {
-      glnx_throw (error,
-                  "--bus-name, --socket or --socket-directory is required");
-      ret = EX_USAGE;
-      goto out;
+      /* We already checked that exactly one of them is non-NULL */
+      g_assert_not_reached ();
     }
 
   if (opt_socket != NULL)
diff --git a/pressure-vessel/portal-listener.c b/pressure-vessel/portal-listener.c
index b28c5a32b0048ff21f25be988c5965e115808f63..d75af840fed4aa773835de7e834376c8a311ff6a 100644
--- a/pressure-vessel/portal-listener.c
+++ b/pressure-vessel/portal-listener.c
@@ -79,6 +79,50 @@ pv_portal_listener_set_up_info_fd (PvPortalListener *self,
   return TRUE;
 }
 
+gboolean
+pv_portal_listener_check_socket_arguments (PvPortalListener *listener,
+                                           const char *opt_bus_name,
+                                           const char *opt_socket,
+                                           const char *opt_socket_directory,
+                                           GError **error)
+{
+  gsize i;
+
+  if ((opt_socket != NULL) + (opt_socket_directory != NULL) + (opt_bus_name != NULL) != 1)
+    {
+      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+                   "Exactly one of --bus-name, --socket, --socket-directory"
+                   "is required");
+      return FALSE;
+    }
+
+  /* --socket argument needs to be printable so we can print
+   * "socket=%s\n" without escaping */
+  if (opt_socket != NULL)
+    {
+      for (i = 0; opt_socket[i] != '\0'; i++)
+        {
+          if (!g_ascii_isprint (opt_socket[i]))
+            return glnx_throw (error,
+                               "Non-printable characters not allowed in --socket");
+        }
+    }
+
+  /* --socket-directory argument likewise */
+  if (opt_socket_directory != NULL)
+    {
+      for (i = 0; opt_socket_directory[i] != '\0'; i++)
+        {
+          if (!g_ascii_isprint (opt_socket_directory[i]))
+            return glnx_throw (error,
+                               "Non-printable characters not allowed in "
+                               "--socket-directory");
+        }
+    }
+
+  return TRUE;
+}
+
 /*
  * If @bus_name is non-NULL, print it to the info fd. Then
  * close the --info-fd, and also close standard output (if different).
diff --git a/pressure-vessel/portal-listener.h b/pressure-vessel/portal-listener.h
index 786546aa9f333cd19805fde652115deaf212cc41..cddb174eb39e3de9d1281d9eae35f297c64b282a 100644
--- a/pressure-vessel/portal-listener.h
+++ b/pressure-vessel/portal-listener.h
@@ -62,6 +62,12 @@ gboolean pv_portal_listener_set_up_info_fd (PvPortalListener *self,
                                             int fd,
                                             GError **error);
 
+gboolean pv_portal_listener_check_socket_arguments (PvPortalListener *self,
+                                                    const char *opt_bus_name,
+                                                    const char *opt_socket,
+                                                    const char *opt_socket_directory,
+                                                    GError **error);
+
 void pv_portal_listener_close_info_fh (PvPortalListener *self,
                                        const char *bus_name);