total;
    bool        dump_grantors;
    bool        dump_grant_options;
+   int         i_role;
+   int         i_member;
+   int         i_grantor;
+   int         i_roleid;
+   int         i_memberid;
+   int         i_grantorid;
+   int         i_admin_option;
    int         i_inherit_option;
    int         i_set_option;
 
     * they didn't have ADMIN OPTION on the role, or a user that no longer
     * existed. To avoid dump and restore failures, don't dump the grantor
     * when talking to an old server version.
+    *
+    * Also, in older versions the roleid and/or member could be role OIDs
+    * that no longer exist.  If we find such cases, print a warning and skip
+    * the entry.
     */
    dump_grantors = (PQserverVersion(conn) >= 160000);
 
    /* Generate and execute query. */
    printfPQExpBuffer(buf, "SELECT ur.rolname AS role, "
                      "um.rolname AS member, "
-                     "ug.oid AS grantorid, "
                      "ug.rolname AS grantor, "
+                     "a.roleid AS roleid, "
+                     "a.member AS memberid, "
+                     "a.grantor AS grantorid, "
                      "a.admin_option");
    if (dump_grant_options)
        appendPQExpBufferStr(buf, ", a.inherit_option, a.set_option");
                      "LEFT JOIN %s um on um.oid = a.member "
                      "LEFT JOIN %s ug on ug.oid = a.grantor "
                      "WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
-                     "ORDER BY 1,2,4", role_catalog, role_catalog, role_catalog);
+                     "ORDER BY 1,2,3", role_catalog, role_catalog, role_catalog);
    res = executeQuery(conn, buf->data);
+   i_role = PQfnumber(res, "role");
+   i_member = PQfnumber(res, "member");
+   i_grantor = PQfnumber(res, "grantor");
+   i_roleid = PQfnumber(res, "roleid");
+   i_memberid = PQfnumber(res, "memberid");
+   i_grantorid = PQfnumber(res, "grantorid");
+   i_admin_option = PQfnumber(res, "admin_option");
    i_inherit_option = PQfnumber(res, "inherit_option");
    i_set_option = PQfnumber(res, "set_option");
 
    total = PQntuples(res);
    while (start < total)
    {
-       char       *role = PQgetvalue(res, start, 0);
+       char       *role = PQgetvalue(res, start, i_role);
        int         i;
        bool       *done;
        int         remaining;
        int         prev_remaining = 0;
        rolename_hash *ht;
 
+       /* If we hit a null roleid, we're done (nulls sort to the end). */
+       if (PQgetisnull(res, start, i_role))
+       {
+           /* translator: %s represents a numeric role OID */
+           pg_log_warning("found orphaned pg_auth_members entry for role %s",
+                          PQgetvalue(res, start, i_roleid));
+           break;
+       }
+
        /* All memberships for a single role should be adjacent. */
        for (end = start; end < total; ++end)
        {
            char       *otherrole;
 
-           otherrole = PQgetvalue(res, end, 0);
+           otherrole = PQgetvalue(res, end, i_role);
            if (strcmp(role, otherrole) != 0)
                break;
        }
 
-       role = PQgetvalue(res, start, 0);
        remaining = end - start;
        done = pg_malloc0(remaining * sizeof(bool));
        ht = rolename_create(remaining, NULL);
                if (done[i - start])
                    continue;
 
-               member = PQgetvalue(res, i, 1);
-               grantorid = PQgetvalue(res, i, 2);
-               grantor = PQgetvalue(res, i, 3);
-               admin_option = PQgetvalue(res, i, 4);
+               /* Complain about, then ignore, entries with orphaned OIDs. */
+               if (PQgetisnull(res, i, i_member))
+               {
+                   /* translator: %s represents a numeric role OID */
+                   pg_log_warning("found orphaned pg_auth_members entry for role %s",
+                                  PQgetvalue(res, i, i_memberid));
+                   done[i - start] = true;
+                   --remaining;
+                   continue;
+               }
+               if (PQgetisnull(res, i, i_grantor))
+               {
+                   /* translator: %s represents a numeric role OID */
+                   pg_log_warning("found orphaned pg_auth_members entry for role %s",
+                                  PQgetvalue(res, i, i_grantorid));
+                   done[i - start] = true;
+                   --remaining;
+                   continue;
+               }
+
+               member = PQgetvalue(res, i, i_member);
+               grantor = PQgetvalue(res, i, i_grantor);
+               grantorid = PQgetvalue(res, i, i_grantorid);
+               admin_option = PQgetvalue(res, i, i_admin_option);
                if (dump_grant_options)
                    set_option = PQgetvalue(res, i, i_set_option);