Android documents three Arm MTE modes. SYNC stops at the exact faulting access and is recommended for testing and critical processes. ASYNC is cheaper and is recommended for production on well tested code. ASYMM checks reads synchronously and writes asynchronously and is preferred over ASYNC when available.
The three modes
SYNC. The check is precise. On a tag mismatch the processor aborts immediately and the process ends with a segmentation fault signal. The crash report includes the memory access and faulting address, and the allocator also records allocation and deallocation stack traces. That makes bugs far easier to diagnose.
ASYNC. The processor continues until the nearest kernel entry and then terminates the process. It does not record the faulting address or the access. Overhead is lower, which is why production use is the recommended fit.
ASYMM. Reads are checked synchronously and writes asynchronously, with performance similar to ASYNC. It is an Arm v8.7-A feature, and the documentation recommends it over ASYNC where available.
Decision guide
- Test and fuzz builds. Use SYNC. You want the address and the stacks.
- Critical processes where exact diagnosis matters. SYNC, as the documentation suggests.
- Production on well tested code. ASYNC, or ASYMM when the hardware supports it.
- Production crash reports you cannot reproduce. Capture the ASYNC report, then rerun the same input under SYNC. The documentation notes that reports from ASYNC processes lack allocation and deallocation stacks, which need SYNC.
Things to keep in mind
- MTE is disabled by default and is a process wide property, so someone has to turn it on per process.
- Tag checks can be suppressed temporarily through a processor state bit, so review code that sets it.
- Coverage in testing may not reach every user scenario, so ASYNC in production complements testing and does not replace it.
- A detected bug stops the process. Plan for crash handling and restarts rather than treating a tag fault as a log line.
Tuning choice
The allocator also has two tunings. The buffer overflow tuning gives deterministic detection of linear overflows between adjacent allocations, with a slightly lower chance of catching use after free. The use after free tuning randomizes tags for about a 93% chance of catching both kinds.
A small test plan
To see the difference on your own code, run the same failing test under each mode on a capable device. Under SYNC you should get a report with the faulting address, the access type and allocation and deallocation stacks. Under ASYNC you will get the crash without that detail. Keep both reports side by side in your team notes, so the next person who sees an ASYNC crash in the field knows what to do with it.
Write the escalation path down. A common pattern is: production ASYNC crash arrives, the team replays the input in a SYNC test build, the report shows the bad access, a fix lands with a regression test that runs under SYNC in CI. The documentation recommends SYNC for testing for exactly this reason.
What about process wide settings
Because MTE is a process wide property, one process cannot mix modes for different components. If one library in a process is not safe to run with tagging, you cannot exempt it alone. Plan for that when choosing which processes to enable first: start with self contained, well understood ones.
Quick check
Which mode gives the exact faulting address?
SYNC. ASYNC does not record the faulting address or access.
Can MTE catch every small overflow?
No. The documentation says it cannot detect an overflow within the same tag granule and can miss small ones.
Sources
Last reviewed: 19 October 2026.