# Tails 7.9 issues

**URL:** https://forum.torproject.org/t/tails-7-9-issues/21783
**Category:** Tails
**Tags:** tails
**Created:** [June 25, 2026, 2:18pm UTC](https://forum.torproject.org/t/tails-7-9-issues/21783 "2026-06-25T14:18:42Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![didi75](https://forum.torproject.org/letter_avatar_proxy/v4/letter/d/c67d28/32.png) [@didi75](https://forum.torproject.org/u/didi75)
#### Post date: [June 25, 2026, 2:18pm UTC](https://forum.torproject.org/t/tails-7-9-issues/21783/1 "2026-06-25T14:18:42Z")

</div>

Hello everyone,

After upgrading to Tails 7.9 and also testing a fresh installation on a new USB drive, I noticed a couple of things that seem unusual and I’m wondering whether they are expected changes or possible bugs.

### 1. Unexpected “~” directory in `/home/amnesia`

I found a directory named `~` inside `/home/amnesia`.

The directory contains:

```auto
~/.local/share/applications

```

However, the `applications` directory itself is empty.

I do not remember seeing this directory in previous Tails releases. Has anyone else noticed it on Tails 7.9? Is this expected behavior or a known issue?

### 2. Monero GUI now reports updates available

Another thing I noticed is that Monero GUI is now informing me that an update is available. I don’t remember seeing update notifications before upgrading to Tails 7.9.

Historically, Tails has blocked non-Tor connections by default, which also prevented some applications’ automatic update checks. For example, older discussions in the Monero community suggested that Tails’ network restrictions would typically prevent the Monero GUI updater from reaching its servers.

This raises a few questions:

- Has anything changed in Tails 7.9 regarding networking rules or application permissions?

- Is Monero GUI now performing update checks over Tor?

- Is the update notification expected behavior in Tails 7.9?

- Could this indicate that some traffic is bypassing previous restrictions, or is there another explanation?

I’m not trying to jump to conclusions, but since both the unexpected `~` directory and the new update notification appeared after upgrading, I’d appreciate clarification from developers or users who have investigated these changes.

Has anyone else experienced the same behavior on Tails 7.9?

Thanks.

---

<div class="post-metadata">

### Author: ![fk11](https://forum.torproject.org/user_avatar/forum.torproject.org/fk11/32/8856_2.png) [@fk11](https://forum.torproject.org/u/fk11)
#### Post date: [July 2, 2026, 8:36pm UTC](https://forum.torproject.org/t/tails-7-9-issues/21783/2 "2026-07-02T20:36:44Z")

</div>

**Issue 1: Literal “~” Directory in /home/amnesia**

On Tails 7.9, a directory literally named `~` appears inside `/home/amnesia/`, containing the path `~/~/.local/share/applications/` (where the first `~` is the actual home directory and the second is a literal directory name). The `applications` subdirectory is empty. This did not exist in Tails 7.8.1.

**Root Cause**

This is caused by commit `df27871`, which introduced a new systemd user service to hide the GNOME Software launcher unless the Flatpak feature flag is enabled. The service file is `tails-possibly-hide-gnome-software-launcher.service`:

```auto
[Unit]
Description=Hide GNOME Software if Flatpak is not enabled
After=gnome-session.target

[Service]
Type=oneshot
ExecStart=mkdir -p ~/.local/share/applications/
ExecStart=/bin/sh -c "(cat /usr/share/applications/org.gnome.Software.desktop \
    && echo 'NoDisplay=true') >> ~/.local/share/applications/org.gnome.Software.desktop"

```

The problem is on the first `ExecStart` line. In systemd service files, the tilde (`~`) is **not expanded** to the user’s home directory. Systemd interprets it as a literal directory name. According to the systemd.exec documentation, only `%h`, `$HOME`, or wrapping the command in `/bin/sh -c` achieve home directory expansion.

The second `ExecStart` line works correctly because it wraps the command in `/bin/sh -c`, where the shell does expand `~` properly. But the first `mkdir -p ~/.local/share/applications/` runs directly (no shell wrapper), so systemd creates a directory literally called `~` in the working directory, resulting in `/home/amnesia/~/.local/share/applications/`.

The fix would be to either use `%h` instead of `~`, or wrap the mkdir command in `/bin/sh -c` like the second ExecStart line does.

**Evidence**

| Item | Detail |
| --- | --- |
| Commit | df278711bc7238a8fac06d4b841b3124f711d019 |
| Title | Hide the GNOME Software .desktop entry unless the flatpak feature flag is enabled |
| File | config/chroot\_local-includes/usr/lib/systemd/user/tails-possibly-hide-gnome-software-launcher.service |
| Bug line | `ExecStart=mkdir -p ~/.local/share/applications/` |
| Fix | Use `%h` instead of `~`, or wrap in `/bin/sh -c` |
| Link | [Hide the GNOME Software .desktop entry unless the flatpak feature flag is enabled (df278711) · Commits · tails / tails · GitLab](https://gitlab.tails.boum.org/tails/tails/-/commit/df278711bc7238a8fac06d4b841b3124f711d019) |

* * *

**Issue 2: Monero GUI Now Reports Updates Available**

On Tails 7.9, the Monero GUI shows an update notification that was not present on Tails 7.8.1. Historically, Tails’ firewall blocked non-Tor connections, which prevented applications like Monero GUI from reaching their update servers. Something changed in 7.9 that allows this to happen now.

**What Changed in Tails 7.9: Reintroduction of Transparent Proxying**

Tails 7.9 reintroduced transparent TCP proxying, a feature that was removed back in Tails 0.10 (circa 2012). All the relevant changes were shipped as part of Merge Request !3009 (“Support installing Flatpak apps”), merged into stable via commit `51bd13ff`.

The key commit is `452facc8` (“Enable transparent proxying through tor for the live user”), which added the following rules to `config/chroot_local-includes/etc/ferm/ferm.conf`:

```auto
table nat chain OUTPUT {
    moduli state (ESTABLISHED RELATED) ACCEPT;
    proto tcp dport 9040 REDIRECT to-ports 9040;
}

table filter chain OUTPUT {
    moduli state (ESTABLISHED RELATED) ACCEPT;
    ... existing per-app ACCEPT rules ...
    policy DROP;
}

```

The `nat OUTPUT` chain now intercepts **all** outgoing TCP connections from the amnesia user and redirects them to Tor’s TransPort on port 9040 via iptables REDIRECT. Tor’s TransPort then reads the original destination using the `SO_ORIGINAL_DST` socket option and routes the connection through the Tor network. This means **any** application that makes a plain TCP connection (without configuring a SOCKS proxy) will now have that connection transparently routed through Tor, rather than being dropped by the firewall.

On Tails 7.8.1 and earlier (since 0.10), the `filter OUTPUT` chain had a `policy DROP` with specific ACCEPT rules only for applications configured to use Tor’s SOCKS port (9050). Any application that did not explicitly use SOCKS would have its connections silently dropped.

The test suite commit `b6273970` confirms this is a deliberate “reintroduction” of transparent proxying. The commit message from `452facc8` explains the rationale:

> “We have no other good way to torify all Flatpaks: torsocks doesn’t work; many applications do not respect the usual environment variables (HTTP\_PROXY, ALL\_PROXY, etc). When we originally stopped doing transparent proxying in Tails 0.10, the motivation was that we would provide high quality per-application configurations for the applications we shipped, but now that we encourage users to install arbitrary applications via Additional Software Packages and now also Flatpak, that is no longer realistic.”

**How This Affects Monero GUI**

The Monero GUI updater uses a two-phase update check. The first phase is a DNS TXT record query performed by the core Monero library inside `Monero::WalletManager::checkUpdates()`. If this DNS query succeeds, it returns a version hash, and the second phase calls `Updater::fetchSignedHash()` which makes HTTP requests to fetch `hashes.txt` and `hashes.txt.sig` from `https://web.getmonero.org/`.

The relevant code in `src/libwalletqt/WalletManager.cpp` shows:

```cpp
void WalletManager::checkUpdatesAsync(
    const QString &software, const QString &subdir,
    const QString &buildTag, const QString &version) {
    m_scheduler.run([this, software, subdir, buildTag, version] {
        const auto updateInfo = Monero::WalletManager::checkUpdates(
            software.toStdString(), subdir.toStdString(),
            buildTag.toStdString().c_str(),
            version.toStdString().c_str());
        if (!std::get<0>(updateInfo)) {
            return; // DNS check failed - silent abort
        }
        // Only reaches here if DNS succeeded
        const QString version = ...;
        const QByteArray hashFromDns = ...;
        Updater().fetchSignedHash(binaryFilename, hashFromDns, signers);
    });
}

```

The critical point: if the DNS check fails (lines 458-460), the function returns silently with no log output and no notification to the user. The `fetchSignedHash()` HTTP call is never reached. This means on 7.8.1, if the DNS check was failing, the update check would abort silently and the user would see nothing.

Now, inside `fetchSignedHash()` in `src/qt/updater.cpp`, the HTTP fetch uses a locally-created `Network` object with an empty proxy address:

```cpp
QByteArray Updater::fetchSignedHash(
    const QString &binaryFilename,
    const QByteArray &hashFromDns,
    QPair<QString, QString> &signers) const {
    const Network network; // local instance, empty proxy
    std::string hashesTxt = network.get("https://web.getmonero.org/downloads/hashes.txt");
    std::string hashesTxtSig = network.get("https://web.getmonero.org/downloads/hashes.txt.sig");
    ... verify and return ...
}

```

In `src/qt/network.cpp`, `Network::get()` calls `set_proxy(m_proxyAddress.toStdString())`. Since `m_proxyAddress` is empty, this sets an empty proxy string on the underlying HTTP client, meaning no explicit SOCKS or HTTP proxy is configured for these requests.

On Tails 7.8.1, these unproxied HTTP connections would be dropped by the firewall’s `policy DROP` in the `filter OUTPUT` chain. On Tails 7.9, the `nat OUTPUT REDIRECT` rule intercepts these connections before they reach the filter chain and redirects them to Tor’s TransPort (9040). Tor then routes them through the Tor network. The connections succeed, the update check completes, and the user sees the notification.

**Why the Update Notification Appeared Now**

The most likely explanation is that on Tails 7.8.1, the GUI updater’s DNS check was failing silently (aborting at the early `return`), so the HTTP fetch in `fetchSignedHash()` was never reached. On Tails 7.9, either the DNS check succeeds (possibly due to changes in how Tor resolves DNS, or it may have been a transient issue on 7.8.1), or some other factor changed. If the DNS check does succeed on 7.9, the HTTP fetch then executes and now succeeds because transparent proxying routes it through Tor, whereas on 7.8.1 it would have been dropped.

**Clarification on the DNS TXT warning in logs:** The warning “WARNING: no two valid DNS TXT records were received” that appears in Monero GUI logs comes from **monerod** (the daemon) and relates to the MoneroPulse DNS checkpoint system. This is a completely separate subsystem from the GUI updater’s version check DNS query. The GUI updater’s DNS query goes through `Monero::WalletManager::checkUpdates()` in the core library and its failure (or success) is not logged at the debug level the user sees. I do not have direct evidence of whether the GUI updater’s DNS query was succeeding or failing on 7.8.1.

* * *

* * *

**Summary**

Issue 1 (the `~` directory) is a straightforward bug in a systemd service file where the tilde character is not expanded because systemd does not perform shell expansion on `ExecStart` commands that are not wrapped in `/bin/sh -c`. The fix is to replace `~` with `%h` on the affected line. This is fully source-verified.

Issue 2 (Monero GUI update notifications) is a consequence of Tails 7.9’s reintroduction of transparent TCP proxying via iptables REDIRECT to Tor’s TransPort (port 9040). The Monero GUI updater creates a local `Network` object with an empty proxy string, meaning its HTTP requests are not explicitly configured to use Tor’s SOCKS port. On 7.8.1, these unproxied connections were silently dropped by the firewall. On 7.9, the REDIRECT rule in the `nat OUTPUT` chain intercepts them and routes them through Tor via TransPort, causing the update check to succeed.

A nuance I want to be upfront about: I cannot confirm from source code alone whether the GUI updater’s DNS TXT query (phase 1) was succeeding or failing on 7.8.1. The function fails silently with no logging. If it was failing, the HTTP fetch was never reached on either version. If it was succeeding on 7.9 but failing on 7.8.1, the transparent proxying change would explain why the HTTP fetch now succeeds when it reaches that stage. Runtime testing with packet capture tools would be needed to confirm the exact behavior.

If anyone has done live testing with Wireshark, sockstrace, or similar tools on Tails 7.9 to verify the actual network behavior, I would be very interested in seeing those results.
