[GH-ISSUE #56] Android AmneziaWG fails to scan QR code from macOS AmneziaVPN when config contains empty I2, I3, I4, I5 fields #31

Open
opened 2026-10-13 21:05:22 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @nia-sempai on GitHub (Feb 16, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-android/issues/56

The problem
When sharing a VPN connection from AmneziaVPN on macOS to AmneziaWG on Android using the "Native AmneziaWG format" QR code, the Android app fails to import the tunnel. It shows a syntax error near "interface" after scanning.

How it breaks

  1. On macOS: Open AmneziaVPN → click "Share" → select "Native AmneziaWG format" → click "Show QR code"
  2. On Android: Open AmneziaWG → tap "+" → "Scan QR code" → scan the code from Mac screen
  3. ❌ Error appears immediately: "Failed to import tunnel: syntax error near 'interface'"
  4. The tunnel is not created and VPN cannot connect

What the QR code contains (simplified version of the broken config):

[Interface]
Address = 10.8.1.11/32
DNS = 1.1.1.1
PrivateKey = xxx...
Jc = 6
Jmin = 10
Jmax = 50
S1 = 71
S2 = 30
S3 = 23
S4 = 8
H1 = 123-456
H2 = 789-012
H3 = 345-678
H4 = 901-234
I1 = <b 0x0844...>
I2 =               ❌ empty field breaks scanning
I3 =               ❌
I4 =               ❌
I5 =               ❌

[Peer]
PublicKey = yyy...
Endpoint = x.x.x.x:port
AllowedIPs = 0.0.0.0/0

How I fixed it
I manually removed all empty fields:

  • Deleted I2 =
  • Deleted I3 =
  • Deleted I4 =
  • Deleted I5 =

After removing these lines, I generated a new QR code (using http://qrcoder.ru/) with the cleaned config. This time VPN connected and works perfectly

Expected behavior
QR codes generated by macOS AmneziaVPN in Native AmneziaWG format should scan and import correctly on Android AmneziaWG without manual editing.

Originally created by @nia-sempai on GitHub (Feb 16, 2026). Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-android/issues/56 **The problem** When sharing a VPN connection from **AmneziaVPN on macOS** to **AmneziaWG on Android** using the "Native AmneziaWG format" QR code, the Android app fails to import the tunnel. It shows a syntax error near "interface" after scanning. **How it breaks** 1. On macOS: Open AmneziaVPN → click "Share" → select "Native AmneziaWG format" → click "Show QR code" 2. On Android: Open AmneziaWG → tap "+" → "Scan QR code" → scan the code from Mac screen 3. ❌ Error appears immediately: "Failed to import tunnel: syntax error near 'interface'" 4. The tunnel is not created and VPN cannot connect **What the QR code contains** (simplified version of the broken config): ``` [Interface] Address = 10.8.1.11/32 DNS = 1.1.1.1 PrivateKey = xxx... Jc = 6 Jmin = 10 Jmax = 50 S1 = 71 S2 = 30 S3 = 23 S4 = 8 H1 = 123-456 H2 = 789-012 H3 = 345-678 H4 = 901-234 I1 = <b 0x0844...> I2 = ❌ empty field breaks scanning I3 = ❌ I4 = ❌ I5 = ❌ [Peer] PublicKey = yyy... Endpoint = x.x.x.x:port AllowedIPs = 0.0.0.0/0 ``` **How I fixed it** I manually removed all empty fields: - Deleted `I2 = ` - Deleted `I3 = ` - Deleted `I4 = ` - Deleted `I5 = ` After removing these lines, I generated a new QR code (using http://qrcoder.ru/) with the cleaned config. This time VPN connected and works perfectly **Expected behavior** QR codes generated by macOS AmneziaVPN in Native AmneziaWG format should scan and import correctly on Android AmneziaWG without manual editing.
Author
Owner

@decide-you commented on GitHub (Feb 18, 2026):

thank you for solution

<!-- gh-comment-id:3922985432 --> @decide-you commented on GitHub (Feb 18, 2026): thank you for solution
Author
Owner

@warment commented on GitHub (Aug 28, 2026):

Workaround: decode the vpn:// export into a plain .conf and import by file

The QR generated by AmneziaVPN (macOS) in "Native AmneziaWG format" is actually an AmneziaQR payload (vpn://… = base64url → zlib → JSON → config string), not a plain WireGuard config. The Android scanner chokes on it with syntax error near 'interface'. This is the same incompatibility the docs admit ("The QR code cannot be scanned if you selected AmneziaWG native format").

Bypass the broken scan entirely: turn that export into a plain text config and import it as a file.

I built a small MIT tool that does exactly this:

pip install "qrcode[pil]"
python3 scripts/decode_amnezia_vpn.py export.vpn -o fixed.conf --png qr.png --mtu 1280
  • fixed.conf → import in AmneziaWG via Import from file (works reliably).
  • qr.png → a QR built from the plain config text, which the scanner accepts.

Repo: https://github.com/warment/amneziawg-qr-fix (releases include a ready script).

One caveat for this specific issue: the tool currently preserves the empty I2 = / I3 = / I4 = / I5 = lines that break Android import in your case. If import still fails after decoding, delete those empty lines (as you did manually) before generating the QR — I'll add automatic stripping of empty AWG fields in the next release. The --raw flag returns the config unchanged so you can edit it.

Root cause worth fixing upstream: the QR/export encoder should emit either a valid plain .conf or a self-consistent AmneziaQR that the same app's scanner can parse — right now it emits the latter but the scanner expects the former.

<!-- gh-comment-id:5450121657 --> @warment commented on GitHub (Aug 28, 2026): ### Workaround: decode the `vpn://` export into a plain `.conf` and import by file The QR generated by AmneziaVPN (macOS) in "Native AmneziaWG format" is actually an **AmneziaQR** payload (`vpn://…` = base64url → zlib → JSON → `config` string), not a plain WireGuard config. The Android scanner chokes on it with `syntax error near 'interface'`. This is the same incompatibility the docs admit ("The QR code cannot be scanned if you selected AmneziaWG native format"). **Bypass the broken scan entirely:** turn that export into a plain text config and import it as a file. I built a small MIT tool that does exactly this: ```bash pip install "qrcode[pil]" python3 scripts/decode_amnezia_vpn.py export.vpn -o fixed.conf --png qr.png --mtu 1280 ``` - `fixed.conf` → import in AmneziaWG via **Import from file** (works reliably). - `qr.png` → a QR built from the *plain* config text, which the scanner accepts. Repo: https://github.com/warment/amneziawg-qr-fix (releases include a ready script). **One caveat for this specific issue:** the tool currently preserves the empty `I2 =` / `I3 =` / `I4 =` / `I5 =` lines that break Android import in your case. If import still fails after decoding, delete those empty lines (as you did manually) before generating the QR — I'll add automatic stripping of empty AWG fields in the next release. The `--raw` flag returns the config unchanged so you can edit it. Root cause worth fixing upstream: the QR/export encoder should emit either a valid plain `.conf` *or* a self-consistent AmneziaQR that the same app's scanner can parse — right now it emits the latter but the scanner expects the former.
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amneziawg-android#31
No description provided.