shortscheck your own page

google oauth · in-app browsers

Error 403: disallowed_useragent

Google blocks its sign-in flow in every embedded browser. Instagram, TikTok, X, Facebook, LinkedIn and Threads all open your link in one.

So the error is not a bug on your page. It is Google enforcing a policy against a browser you did not choose and cannot change.

Below: the exact wording, what the answers on this error get wrong, and the one place the problem can still be fixed.

what Google returns

403. That’s an error.

This user-agent is not permitted to make OAuth authorisation request to Google as it is classified as an embedded user-agent (also known as a web-view). Per our policy, only browsers are permitted to make authorisation requests to Google. We offer several libraries and samples for native apps to perform authorisation request in browser.

error=disallowed_useragent · disallow_webview=true

Inside Instagram’s own browser you often see no error at all. The screen turns white after the visitor submits their password, and they leave.

why it fires

Google announced the block in June 2021 and enforced it on 30 September 2021. The reason given is that whoever embeds a browser can read what you type into it.

Embedded webview libraries are problematic because they allow a nefarious developer to intercept and alter communications between Google and its users by acting as a “man in the middle.”
Google, upcoming security changes to the OAuth 2.0 authorization endpoint in embedded webviews

The policy itself is one sentence, and it has no exception for an app that embedded the browser without asking you.

A developer must not direct a Google OAuth 2.0 authorization request to an embedded user-agent under the developer’s control.
Google, OAuth 2.0 policies, use secure browsers

The IETF says the same thing in RFC 8252: native apps must not use embedded user-agents for authorisation requests.

This is why the error surprises people. You did not embed anything. Instagram did, and Google is refusing that browser on sight.

who embedded the browser

  • your own app with a WebViewyou can fix this, and Google documents how
  • Instagram, TikTok, X, Facebook, LinkedIn, Threadsyou cannot change their browser
  • the phone's Chrome or Safarisign-in works normally, sessions and autofill included

what does not work

Most published answers to this error are stale. Here is each one and the reason it fails today.

  • spoofing the user-agent string

    The highest-voted answers set a Chrome user-agent on the WebView. Google now reads more than that string, and commenters on the same answers report the error returning unchanged.

  • window.open with a chrome: or custom scheme

    Tried and reported as not working from inside the embedded browser. An external browser will not launch from a script that no one tapped.

  • switching the popup flow to a redirect flow

    Worth doing, and it fixes a different failure: a popup that cannot open in a single-tab in-app browser. Google still answers disallowed_useragent to the redirect.

  • hiding the Google button when you detect a webview

    This is damage control, not a fix. The visitor stops seeing a broken button and loses the sign-in method they wanted.

  • asking the visitor to use the open-in-browser menu

    The menu is real, in the corner of someone else's app, behind three dots. Most people do not go looking for it.

The pattern is the same in all five. Once your page is rendering inside Instagram, the browser is already the wrong one, and nothing in your page can change it.

what works

There are two real fixes, and which one applies depends on who opened the embedded browser.

if your own app embeds the browser

use the platform's real browser component

Google names both replacements. On Android, open sign-in in Android Custom Tabs instead of a WebView. On iOS, use SFSafariViewController rather than WKWebView.

Both are policy-compliant, because both are the phone’s browser with your app around it. This ends the error outright.

It does nothing for taps that arrive from Instagram, because that browser is not yours.

if your taps arrive from social apps

escape at the link, before the page loads

The tap is the only user gesture you get. A link that resolves on a server can send the destination to Chrome or Safari at that moment, using the escape each platform accepts.

Your page then renders in the browser where the visitor’s Google session and saved passwords already are, and sign-in behaves normally.

This is the only fix available to you when someone else owns the browser.

Being plain about our own position: the second fix is what shorts is. We built it because we had the problem, and this page is accurate whether or not you use it.

You can also build it yourself. The parts are a redirect service, per-platform escape handling, and somewhere to count what happened.

does your page have this problem

Paste your signup or login page. We read it once and name every sign-in button that cannot complete inside an in-app browser. No account.

we read the page once and tell you what breaks. free, no account, nothing stored about you.

We have read the signup pages of well-known products the same way, and most of them offer a sign-in that cannot complete there. That is the report.

A shorts link does the escape and counts every tap by source app. free keeps 5 links and 30 days of taps. shorts Lifetime is $49 once, with nothing recurring.

short answers

What does Error 403: disallowed_useragent mean?
Google refuses to run its OAuth sign-in flow inside an embedded browser. Every in-app browser is one, so the error is the policy working, not a bug in your page.
Why do I get it when I never embedded a webview?
Instagram, TikTok, X, Facebook, LinkedIn and Threads open your link in their own embedded browser. Google sees that browser, not the one on the phone, and refuses.
Does changing the user-agent string fix it?
No. It worked until Google tightened detection past the user-agent string, and the answers recommending it are from 2016 to 2019.
Can my page force the in-app browser to hand off to Chrome or Safari?
Not from a script on page load. An external browser only opens from a real tap, so the escape has to happen at the link, before your page renders.
What can I do about taps that already arrived in an in-app browser?
Very little. Once your page is rendering inside Instagram, Google will refuse, and asking the visitor to find the open-in-browser menu loses most of them.