User-agent strings are weird. They inform the server which application is communicating with them. In the case of a web browser, this string can contain the name and version of the browser, but also information about the operating system and the device on which the browser is running.
But browsers lie. They lie a lot, sometimes for historical reasons and sometimes for compatibility reasons. And sometimes, because they want to limit the information in the user-agent string to reduce the fingerprinting surface and improve the privacy of the user. I’ve written about this extensively in the “The problem with User-Agent strings” series of articles.
This article is a tiny update about what is currently happening with the upcoming release of Safari 26 on iOS, iPadOS and macOS. And this release is particularly interesting because Apple decided to skip a whole bunch of versions for marketing reasons. In the past, the major version was increased every year. In the new scheme, the major version is the year in which the browser is released, plus one. The previous version of Safari was version 18.6. The latest version is Safari 26.0, corresponding to the current year, 2025. Totally makes sense, right?
How does this affect the user-agent string of Safari on iOS?
So, during the whole beta cycle for iOS 26, I’ve seen multiple user-agent strings in use.
At first, we saw that Apple increased the version token in the User-Agent string by one, and also updated the version of the operating system. That makes sense because Apple had been working on version 19 for a long time internally before the decision to use a new versioning scheme.
Mozilla/5.0 (iPhone; CPU iPhone OS 19_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/19.0 Mobile/15E148 Safari/604.1
A bit later in the beta cycle, we saw Safari move to version 26 for the browser and iOS 26 for the operating system. Curiously, the change for Safari and iOS did not happen at the same time. For a short time we can see user-agent strings with Safari 26 running on iOS 19. But eventually both caught up and both were changed to 26.
Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1
But this also changed. I am currently running the latest betas, and the version of iOS has changed to something else. Not 19, not 26. But the version of Safari itself has not changed. That is still version 26.
Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1
Instead of running on iOS 26, we are now running on iOS 18.6, the latest release of iOS 18. This is a lie, of course. But, is this a mistake? Probably not.
We’ve seen something similar a couple of years ago with Safari on macOS. Apple has set the version number of macOS to a fixed number in the user-agent string of Safari. If you run Safari on a Mac, it will always tell the server it is running on an Intel Mac, running macOS 10.15.17. It is no longer possible to tell the operating system version from the User-Agent string. Of course, you can deduce a reasonable range of versions from the version of Safari. For example, we know Safari 17 was released together with macOS 17. Each version of Safari is also released for the two previous versions of macOS. We can therefore determine that the user is running either macOS 15, 16 or 17. You can read more about this in the article “Trouble happens when you update a version number“.
The same thing appears now to happen with iOS. The version of iOS is fixed, and we can no longer tell the version of iOS. But unlike on macOS, each version of Safari is tightly coupled to a specific iOS release. Therefore, based on the version number, we can still confidently state that the user is using iOS 26.
Update: Confirmed by Karl Dubost from the Safari team! This is about reducing the fingerprinting surface of the user-agent string, as described here: User-Agent reduction.
But what about other browsers?
The version number of the User-Agent string is only fixed in Safari, not the WebKit rendering engine that all browsers on iOS still use. That means that other browsers, by default, will give us accurate information about the operating system.
For example, for Chrome:
Mozilla/5.0 (iPhone; CPU iPhone OS 26_0_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/138.0.7204.119 Mobile/15E148 Safari/604.1
And Firefox:
Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/140.2 Mobile/15E148 Safari/605.1.15
And Safari:
Mozilla/5.0 (iPhone; CPU iPhone OS 26_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1
Wait… what? Safari? This is probably not Safari. It is a third-party browser that does not have its own user-agent string. It simply uses the default WebKit one, which states that it is Safari
and utilises the correct version of the operating system.
And how about iPadOS?
The user-agent string of the iPad is a story in itself, starting with iPadOS 13 in 2019. That was the first version of Safari on iPad that supported “desktop” browsing. Apple put a lot of work into making the Safari browser on iPad more capable, comparable with Safari on macOS. But the user-agent string was traditionally very similar to the user-agent string of Safari on iOS. So, Apple decided to change the user-agent string to be indistinguishable from that of macOS. So users of Safari on iPad would get the desktop version of sites, instead of mobile versions.
With iPadOS 26, this is still true. It uses the exact user-agent string as macOS:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15
It is still possible to turn off “desktop” browsing and request a mobile version of a website. When you do that, you’ll get something like this:
Mozilla/5.0 (iPad; CPU OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1
Very similar to iOS, including the fixed version of 18.6 and a Mobile
token to indicate we want a mobile version of the website. Unlike the iOS user-agent string, which states that it is running on an iPhone, this one explicitly mentions the iPad.
But what about third-party browsers? This is again very similar to what is happening on iOS. For example, Chrome on iPad:
Mozilla/5.0 (iPad; CPU OS 26_0_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/138.0.7204.156 Mobile/15E148 Safari/604.1
This time, the iPad is specifically mentioned again, and we have the correct version of the operating system. This is consistent with the fact that “desktop” browsing and the fixed version number are both Safari-specific implementations and are not built into the WebKit framework that Chrome uses on iOS and iPadOS.
And now Safari 26 on macOS…
We’ve already seen the macOS user-agent string when we talked about iPadOS, as they are precisely the same:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15
What we can see here is that the version of macOS is still fixed to macOS 10.15.7. This has been the case for the last couple of years, and it is no surprise that Apple did not update it this year. That said, it becomes increasingly bizarre to see browsers claiming to run on an operating system from 2019.
Other than that, Apple only changed the version number of Safari itself using the Version
token. Similar to previous years, we can tell the user is using at least the current version of macOS or two versions older.
And for third-party browsers? That depends.
Chrome, for example, also fixed the version of the operating system, so it is not possible to figure out the version number of the operating system from the user-agent string. But it does support the User-Agent Client Hints API, which will report the correct version.
The User-Agent Client Hints API
That brings us to the last thing I want to discuss. Safari 26 still does not support the User-Agent Client Hints API. Nor does Firefox, so for now this API – which is supposed to be a more privacy-friendly replacement for the User-Agent string – remains a Chromium-only feature.