I'm pretty sure I discovered the bug, and I think I know how to rectify it too. Please note that this was a tricky bug to find and it made my head spin for a while; it was only recently when I figured this out from start to end. Here's what I know now: I discovered that Ubiquity's greeter (`maybe-ubiquity`) starts two D-Busses: the normal session bus, which non-root programs communicate over for pretty much everything (including accessibility communications), and the special accessibility bus, which is only used by root programs like Ubiquity. The accessibility bus uses a special configuration file which allows root to use the bus (normally root would be banned from the bus); that configuration file is stored at /usr/share/defaults/at-spi2/accessibility.conf: [...] [...] Depending on the version of Ubuntu in use, the exact application which requests the accessibility bus in the first place (and thus the application which requests the bus to be launched) differs. On stock Ubuntu, it is a portion of the GNOME Settings Daemon; on Ubuntu MATE, it is consistently the Ubiquity panel. Either way, which application starts the bus doesn't matter, as long as an application starts it. When an application requests the bus be started, the D-Bus daemon requests that SystemD launches the `at-spi-bus-launcher` program. This program starts another, separate D-Bus daemon (separate from the main session bus, that is), and tells this new D-Bus daemon to use the aforementioned configuration file. The bus launcher also requests that the new D-Bus daemon inform the bus launcher about how the new D-Bus daemon can be addressed and contacted; the applications need to know about this bus and they need to know how to communicate on it. The D-Bus daemon tells the bus launcher how to contact it when the D-Bus daemon has initialized itself fully. Once the bus launcher knows how to contact the accessibility bus, the bus launcher is supposed to set an *X11 atom* on the root window of the X session which Ubiquity is using. The atom applied to the root window means that any application, even Ubiquity, can quickly and easily find out how to communicate over the accessibility bus. Here's an example of the atom: $ DISPLAY=":0" xprop -root AT_SPI_BUS AT_SPI_BUS(STRING) = "unix:abstract=/tmp/dbus-jvfzJSsTTp,guid=e1dc67ddfb5b08287b1b9676612460d8" This means that the accessibility bus can be reached using a UNIX domain socket (so it can be accessed only on the local system); a proper call to "bind" to the socket at `/tmp/dbus-jvfzJSsTTp` will connect to the accessibility bus (though the `abstract` part means that the socket is not visible in the file system; this is a Linux-only feature, and you'll sometimes see `path` instead, which means the socket can be viewed as part of the file system); and in order to verify that the application is authenticated to access the bus, it must pass the globally unique identifier `e1dc67ddfb5b08287b1b9676612460d8` as proof that it's not an external attacker. Sounds straightforward, right? Wrong. How does the bus launcher know what the address of the *X server* is? Sure, there is the `DISPLAY` environment variable, and that is what the bus launcher tries to get access to; but in general, on UNIX one process cannot get access to an environment variable unless it inherited that variable from its parent. So who's the parent of the bus launcher? You'd think it would be the Ubiquity panel, for example, or the GNOME Settings Daemon, since those programs *requested* the accessibility bus in the first place. Not so; remember how I said that *the Ubiquity panel requests* that *D-Bus requests* that *SystemD launches* the accessibility bus? (Yes, it really *is* that big of a game of Telephone.) But the D-Bus session bus daemon doesn't know what the contents of the X11 `DISPLAY` variable are -- I verified this -- much less does SystemD know that. So how is the accessibility bus supposed to know what X11 display to use?? This one took a lot of digging. Ultimately, it was just luck that I came across the `/usr/bin/ubiquity-dm` program, which holds the key (excerpted from line 407 et seq.): if ( osextras.find_on_path("kwin") or osextras.find_on_path("kwin_x11") or osextras.find_on_path("gnome-shell") ) and osextras.find_on_path("dbus-update-activation-environment"): subprocess.Popen( [ "dbus-update-activation-environment", "--verbose", "--systemd", "DISPLAY", ], stdin=null, stdout=logfile, stderr=logfile, preexec_fn=self.drop_privileges, ) Okay, what's going on here? Let's break this down: If KWin or the GNOME Shell are installed, and this program called `dbus-update-activation-environment` is also installed, then run this `dbus-update-activation-environment` program -- with a parameter of `DISPLAY`. Huh. Does that sound familiar? The Ubiquity panel asks D-Bus to *activate* the accessibility bus (I verified that is the proper terminology). I looked up this interesting command, and I confirmed that this command tells D-Bus what environment variables to provide to activated services. In other words, this command tells D-Bus to launch any future services (such as the accessibility bus launcher) with an extra environment variable: `DISPLAY`! So this is how the bus launcher finds the X11 display, adds the atom, and informs other applications (notably Ubiquity) how to access the accessibility bus. But one little problem remains. Did you notice that the above only applies to stock Ubuntu or Kubuntu, or a strange "spin" of Ubuntu which includes at least either KWin or the GNOME Shell? Did you notice there was nothing for, for example, a distribution like Ubuntu MATE which doesn't include either program? That's right, that's where the bug lay. I tried changing `gnome-shell` to `geenome-shell` (that does not exist) on stock Ubuntu, and Ubiquity wouldn't communicate with the screen reader anymore -- just like Ubuntu MATE. And I tried changing that to `marco` on Ubuntu MATE, and it worked! So who introduced this bug, and why? I don't know. What I do know is that, after I looked briefly through the list of commits to the Ubiquity repo on Launchpad, I noticed a change from January which basically stated "Add screen reading capabilities to Kubuntu" (see https://git.launchpad.net/ubuntu/+source/ubiquity/commit/bin/ubiquity-dm?id=365ce53aa2beb6dad17234aaa5789a68c2220438). Well, excuse me. Do we really need to add support for each derivative of Ubuntu separately? This program (`ubiquity-dm`) already assumes that we have a GUI (as opposed to the server installer, which has no GUI). Can't we just remove the `if kwin ... gnome-shell` stuff so that all derivatives of Ubuntu can benefit? I think the answer is "yes", based on my research into the commit history of the repo. And as soon as I can, I shall start a merge request and get this patched up ASAP. We don't need any more visually impaired users suffering from this tricky bug. I have not declared victory yet; I shall declare it only after someone else confirms what I have written, and the patch is applied. But I'm still pretty happy right now that I think I've found the problem, anyway. That was a long rant, but I hope I didn't leave anything out! **EDIT:** I just opened a merge request to resolve this: https://code.launchpad.net/~thesquash/ubuntu/+source/ubiquity/+git/ubiquity/+merge/407632