Docket / Fix it / phone links that will not dial

Phone links that will not dial

Somebody reading your site on a phone taps your number. Does it dial? The page was written on a desktop and it is checked on a desktop, and on a desktop tapping a number is not something anybody does — so the link can be broken for years while every person who looks at the page sees a phone number that is perfectly correct.

Docket's cvr.unusable_phone reads the href of every tel: link on the pages it crawls and reports the shapes that cannot place a call: letters where the digits should be, markup pasted into the number, a single repeated digit at full number length, and a national number with neither a country code nor a phone-context parameter. Each is reported as its own finding, at its own severity, because the repairs have nothing in common.

What this cannot tell you

Said first, because it decides whether the finding is worth anything to you. Docket does not ring the number. No call is placed, nothing is looked up in a numbering plan, and no operator is asked whether the line exists.

So it cannot tell you the number is answered, that it is still yours, that it is current, or that the person who used to pick it up still works there. It reads your markup and answers one question: will tapping this place a call. A number that is well formed and simply wrong — last year's line, two digits transposed, the office you closed — is a valid tel: URI and this check has nothing to say about it. Closing that gap would mean dialling strangers' phones from an audit tool, which we are not going to do.

What counts as a phone number here

Only a tel: link in the markup. A number sitting in prose is not read by this check, and the comment in the source says why: a number in prose may be an example, a fax, or a customer's. The same reasoning covers a tel: that appears inside a JavaScript string — a grep finds it, the parser does not, and the parser is right, because a mention is not a promise.

A printed number with no link on it at all is a different check in a different lane (local.phone_not_clickable, which only runs for sites that look like a local business). This page is about the link that exists and does not work.

Before anything is judged, the href is percent-decoded. That is not housekeeping. A site writing tel:0333%200146%20683 is writing spaces; filtering that for digits without decoding it first turns every %20 into a 2 and a 0 and invents a number nobody published. Anything after a semicolon is a parameter and not part of the number.

The shapes it reports

Letters in the href

A vanity number in the link itself. RFC 3966 section 5.1.2 does not support the notation, because the mapping from letters to keypad digits is not uniform internationally, so the link dials nothing anywhere. Reported at HIGH, and the fix text is careful about which half is wrong: "Keep the memorable number as the visible text and put digits in the href: <a href="tel:+YOURPHONENUMBER">YOUR MEMORABLE NUMBER</a>." The printed number can stay exactly as it is. Only the thing behind it changes.

HTML where the number should be

An entire anchor tag pasted into the CMS field that expects a phone number, and escaped by the CMS on the way in — so the dialable part of the href is markup. It is reported separately, as cvr.phone_href_markup, and the separation was earned. The letters rule used to catch this case and tell the owner to "put digits in the href", which they already had: the visible text was an ordinary formatted number and the digits inside the pasted tag were fine. Advice describing work that is already finished leaves a reader one conclusion, and it is that the tool is broken.

So this finding says, in as many words, that the page still looks right, and its fix points at the field rather than the copy: "Open the phone-number field in your CMS and look at what is actually stored in it. Clear it and type the number by itself — digits and separators only, no <a> tag — and let the template build the link around it."

A placeholder nobody filled in

Every digit the same, at seven digits or more. A template that shipped with the example still in it, reported at HIGH, and the fix is one line: "Replace it with the real number, or remove the link."

The length floor is there because of a real accusation. Without it, the rule fired on 111 — a national non-emergency health line — and said anyone tapping it reaches nobody. 999, 911, 000 and 112 have exactly the same shape. A repeated digit is only evidence of an unfilled template at full number length; shorter than that it is a short code, and short codes are precisely the numbers a health or emergency service publishes.

A national number with no way to reach it from outside

RFC 3966 section 5.1 is blunt about this: all phone numbers must use the global form unless they cannot be represented that way, and a local number must carry a phone-context parameter naming where it is valid. A bare national number has neither. It dials correctly from inside the country and incorrectly from outside it — a total failure for a visitor abroad and none at all for one already there.

So the severity follows what the site itself declares. LOW by default. MEDIUM where the site publishes hreflang, because a site with hreflang has said it wants visitors who would be dialling from abroad. That is read from the markup rather than guessed from the kind of business. The fix again leaves the printed number alone: "Prefix the country code and a plus in the href, leaving the visible text alone: <a href="tel:+YOURPHONENUMBER">YOUR PHONE NUMBER, spaced as you print it</a>."

The global form is the + and the country code (RFC 3966 section 5.1.4). The sanctioned alternative for a number that genuinely cannot be written that way is the parameter: tel:5551234;phone-context=+1, or a domain you control (RFC 3966 section 5.1.5). Docket accepts either and says nothing.

Where the check and the specification disagree

Stated here, because this is the wrong page to hide them.

Short codes get advice the specification says cannot work. A bare 111 or 911 in an href is still reported as not being in international format, and the fix text offered is "prefix the country code". RFC 3966 section 5.1 says emergency and service numbers cannot be represented in global form and must be tagged with a phone-context instead; it points out that +1-911 is not a valid global number. The finding is defensible — a local number with no context genuinely is outside the specification — and its remedy is not the one the specification gives. The placeholder rule was taught about short codes. This branch has not been.

Spaces are tolerated and the specification forbids them. RFC 3966 section 5.1.1 says a tel URI must not use spaces as visual separators. Docket reads tel:+44 20 7946 0958 and reports nothing at all. That is the check being deliberately narrow rather than specification-complete: it reports the things that stop a call being placed, and a space does not. Worth knowing if you are validating against the standard rather than against what a handset does.

Every reading of the specification on this page is from RFC 3966, the tel URI scheme, read at rfc-editor.org on 15 September 2026.

One number in a template is one number

A phone number lives in the header, or the footer, or both — which means a site that writes it wrongly writes it wrongly everywhere. The finding therefore names the distinct numbers and counts the pages, not the links. That matters for the size of the job it seems to describe: the repair is one line of a template, and a finding that counted occurrences read as a morning's work.

Checking your own, without a tool

Read the hrefs rather than the page:

curl -s https://example.com/ | grep -o 'href="tel:[^"]*"'

What you want back is a +, a country code, and digits. What you do not want is a letter, an angle bracket, or the same digit over and over. This will also show any tel: written inside a script, which Docket ignores — so read what it prints rather than counting it.

Then do the thing the desktop cannot do: open the page on an actual phone and tap the number. The whole class of failure exists because that step is the one nobody takes.

The same failure, one channel over

An email address on a domain that cannot receive mail fails in the same silent way, and that one we have measured. Among UK shop websites sampled from OpenStreetMap, 20.9% publish an address in a mailto:, and 7 of the 413 domains publishing one cannot accept mail — the survey and its limits are on that page. It measured MX records. Nothing in it is a measurement of phone links, and that rate does not carry across to them; we have not surveyed phone links at all.

If your customers find you in a map, the rest of that ground — business schema, the name, address and phone matching your listing, the place named in your titles — is on why your business is not in the map pack. The lane this check sits in, and what else is in it, is on the conversion audit page.

Download Docket

Common questions

Why does a tel: link work on my desktop but not on a phone?

It does not work on either. Nobody taps a phone number on a desktop, so the failure only shows itself on the device you are not testing on.

Does Docket call the number to check it?

No. It reads the href and reports whether tapping it would place a call. It cannot tell you the line is answered, that the number is current, or that it is still yours.

Can I keep a memorable vanity number on the page?

Yes. Keep it as the visible text and put digits in the href. The tel URI scheme does not support letters, because the mapping from letters to keypad digits is not the same in every country, so a vanity href dials nothing.

Do I have to write my number in international format?

RFC 3966 says all phone numbers must use the global form — a plus and a country code — unless they cannot be represented that way, and that a local number must carry a phone-context parameter saying where it is valid. Docket reports a number with neither at LOW, or at MEDIUM where the site publishes hreflang and is therefore asking for visitors who would dial from abroad.

Why is my emergency or service short code being reported?

Because it has no country code and no phone-context parameter, so it falls into the not-in-international-format branch. The advice offered there does not fit it: the specification says service and emergency numbers cannot be written in global form and should carry a phone-context instead. It is a gap in the check, and it is the reason the placeholder rule ignores anything shorter than a subscriber number.

What does phone-context do?

It names the scope in which a local number is unique — a country dialling prefix, or a domain you administer. A local number plus its context is globally unique again, which is what makes the link usable from outside.