Launching the WireGuard activity brings an app to the front, not a particular tunnel up. An automation that opens the app and waits will pass in testing and fail the first time the phone is already sitting on the home screen. WireGuard exposes a supported remote-control path for named tunnels, and it is narrower than most recipes suggest. The checklist below walks that path from permission to observed result.

Check that remote control is enabled

The remote-control receiver is not always listening. WireGuard settings include an option that enables remote control of tunnels, and until that option is on the receiver ignores requests instead of failing loudly. The default is deliberate, because an exported receiver that could bring tunnels up would be a security hole on every device that installed the app. Enable it through the interface and write down that you did, since it is a setting a future user can switch off without knowing what depended on it.

The upstream receiver handles only named UP and DOWN requests, so there is no path here for creating a tunnel or editing its configuration. Confirm the component exists in the installed build before relying on it: adb shell dumpsys package com.wireguard.android | grep -i receiver lists the declared receivers, and a build without the remote-control receiver will never answer. If the workflow needs a different endpoint or a different peer, that is a different tunnel and a separate manual setup inside the app.

Check the permission the controller holds

WireGuard protects the receiver with a dangerous permission, com.wireguard.android.permission.CONTROL_TUNNELS, which the controlling app has to hold. A custom broadcast cannot manufacture a permission that the sender never declared or was never granted. This is the step where automation recipes quietly assume a capability the automation does not have.

Check both sides before writing the task. The first command lists the declared permission, and the second shows whether the controller package actually holds it. A controller that declares the permission in its manifest but was never granted it at runtime still fails, and the failure arrives as silence rather than as a dialog.

adb shell pm list permissions -g -d | grep -i control_tunnels
adb shell dumpsys package net.dinglisch.android.taskerm | grep -i control_tunnels

If the controller does not hold the permission, use the integration the app actually supports instead of hand-building a broadcast. Sending an intent and observing that the call succeeded proves only that Android accepted it, not that WireGuard acted on it. Treat an unverified send as an unknown, not as a success.

Check the intent fields against the installed app

Four fields carry the whole request, and each one has a failure mode that looks exactly like the others. Get the action, the tunnel extra, the package and the target right as a set.

Action:  com.wireguard.android.action.SET_TUNNEL_UP
Extra:   tunnel:lab-wg
Package: com.wireguard.android
Target:  Broadcast Receiver

The action names UP or DOWN and nothing else, the extra carries the exact configured tunnel name, the package restricts delivery to WireGuard, and the target has to be the receiver rather than an activity. A tunnel name with a typo produces the same silence as a disabled receiver, so read the name in the app before concluding that the automation is broken. The DOWN action is com.wireguard.android.action.SET_TUNNEL_DOWN with the same extra and package. Send one request at a time while testing, because two broadcasts racing each other produce a state nobody can attribute.

Test the same request from a shell on the device to separate the intent from the automation. If that command fails while the Tasker task succeeds, the difference is the sender permission rather than the field values.

adb shell am broadcast -a com.wireguard.android.action.SET_TUNNEL_UP -e tunnel lab-wg --receiver-permission com.wireguard.android.permission.CONTROL_TUNNELS

Check what the trigger does not cover

An app-launch or foreground event can request a connection, but the app may already have attempted a name lookup or an initial request before that event is handled. The trigger fires when the system notices the state change, which is after the app started doing work. If the app must never communicate outside the tunnel, a launch trigger is not a blocking rule and cannot be turned into one by adding a delay. Configure a supported always-on or per-app policy for the blocking behaviour, and keep the trigger for convenience only.

The blocking behaviour lives somewhere else entirely. adb shell settings get global always_on_vpn_app names the package pinned as always-on, and adb shell dumpsys connectivity | grep -i vpn shows the VPN networks the system currently tracks. Neither of those is something a launch trigger can substitute for.

The same reasoning applies at the other end of the session. Bringing the tunnel down because one window lost focus breaks background work, authentication helpers, and any other app that was relying on the connection. Define a deliberate end of session rather than a focus change, and avoid rapid UP and DOWN sequences when the automation switches contexts.

Check the result instead of the send

A broadcast that returns without an error has been accepted by Android and nothing more. Read the tunnel state from the app, and read the workflow readiness from whatever the next step actually needs. Those are two different checks, and passing the first one does not imply the second.

Read the interface state directly as well: adb shell ip -brief addr show tun0 prints the tunnel interface and its address, and an interface that exists with no address is up without being usable. Then verify the private service itself, because a tunnel that is up with no handshake or no route still fails the task that mattered. An automation that controls one named connection within its real permission boundary does not need to tap the interface, run a root command, or weaken Android network protections.

Artaigilean co-cheangailte