Home / Guides

The email that left in plain text

Enhanced Conversions has exactly one hard requirement, and it is the one nothing in the Google Ads interface will tell you about for days: the customer data has to be hashed before the request leaves the browser. Here is how to read that off the hit.

Enhanced Conversions works by sending customer data alongside the conversion so Google can match it to a signed-in user whose click was not otherwise attributable. The whole mechanism rests on one requirement: that data is hashed with SHA-256 before it leaves the browser. Google never receives the address; it receives a digest and compares digests.

When that requirement is not met, two things happen at once. The match rate quietly fails to improve, and a customer email address has been transmitted in the clear to an advertising endpoint. The first is a measurement problem. The second is the kind of problem that involves other departments.

What a correct field looks like on the wire

There are two legitimate shapes, and it is worth knowing both because implementations differ:

Everything else is a defect, and the four you will actually meet are these.

A Google Ads conversion expanded in the panel, badged Enhanced Conversions and PII, with Email and Phone marked SHA-256 and ticked while First Name is marked plaintext and flagged, above a
Two fields hashed and one that was not. The shape of a value is enough to catch this one; the two failures that look exactly like success — a hash of an unnormalised string, and a value hashed twice — are not in this picture and never will be.

Tag Master validates the fields on every Google Ads conversion it sees and says which shape each one is in: SHA-256, MD5, or plaintext with a warning attached. It reads the tv.1~ envelope rather than treating it as an unhashed string, because a tool that cried wolf on the correct implementation would be worse than no check at all.

The four ways it goes wrong

  1. Plaintext. The value in em is still an email address, usually because a dataLayer variable was wired straight into the user-data field on the assumption that the tag would hash it. Sometimes it does; when the value arrives through a variable rather than page collection, it does not.
  2. MD5. Thirty-two hex characters. An older internal hashing helper, reused. The request succeeds and matches nothing.
  3. Hashed without normalising. This is the expensive one, because everything looks right. [email protected] and the same address with a capital A, or with one trailing space, produce three completely different digests. Trim the whitespace, lowercase the address, strip dots and plus-tags only where Google says to, and put the phone in E.164 form before hashing — otherwise you are sending a valid hash of the wrong string.
  4. Hashed twice. Code hashes the value and the tag hashes it again. Sixty-four hex characters, perfectly formed, matching nobody.

Only the first two are visible as shape. The last two look identical to success, which is why the check has to include reading the value you put in, not only the value that came out.

Why the interface will not tell you

Google Ads diagnostics reports on conversions it has already processed, days later, and what it reports is coverage: how many conversions carried user data. It cannot report that a digest was computed over an unnormalised string, because from Google’s side that is simply a hash that did not match. Two indistinguishable outcomes, one of them your bug.

The request is immediate and unambiguous by comparison. Do a test conversion, read the hit, confirm the shape of every field, and you have an answer in a minute rather than a week.

Two things to check while you are in there

First, the attribution half. Enhanced Conversions improves matching; it does not replace the click chain. If the conversion carries no gclid and no linker cookie, there is a separate problem underneath this one, and the campaign that brought the visitor is where it starts.

Second, consent. User data leaving the browser while ad_user_data is denied is a worse version of the same finding, and it is not something the Google Ads interface will surface either. Reading the consent state carried on each hit is how you tell whether the request should have been sent at all.

Questions

How do I check that Enhanced Conversions data is hashed?

Read the conversion request. A hashed field is 64 hexadecimal characters, or the Google tag’s envelope tv.1~em.<hash>~ph.<hash>. Anything that still looks like an email address is plaintext, and that is a policy problem as well as a broken setup.

Which fields have to be hashed?

em, ph, fn, ln, ct, st and zp. country is the exception — it travels as a plain ISO 3166-1 alpha-2 code and is meant to.

Is MD5 acceptable?

No. Google Ads takes SHA-256 only. An MD5 digest is 32 hex characters instead of 64, so it is recognisable on sight — and it will be accepted by the request and match nothing.

Why does the Google Ads diagnostics page say everything is fine?

Because it reports on data already processed, with a lag measured in days, and it reports coverage rather than correctness. A field hashed without normalising it first produces a valid-looking hash that matches nobody, and diagnostics has no way to say so.

Doing this in the panel →

The rest of this group: GA4, server-side and attribution

More in GA4, server-side and attribution

Try it on your own site

Tag Master is free, needs no account, and collects no data.

Add to Chrome — Free