Software versioning best practices for vendors | Versio.io

Software versioning best practices

Five recommendations for software vendors on product names, version identifiers, lifecycle data and vulnerability advisories

In a nutshellRequest demoStart free trial
 

Why version identifiers matter

A version identifier is far more than a label on a download page. It is the key that connects an installed product with its release date, its support period and its known vulnerabilities. If this key is ambiguous, every process that relies on it becomes unreliable: vulnerability scanners report false positives or, even worse, miss real vulnerabilities, end-of-life warnings arrive too late and patch decisions are based on guesswork.
One product, five identities: Brave release 1.97.56 appears with different product names and versions in the release notes, on Windows, on macOS, in the Linux package and in the NVD CPE dictionary
XOne product, five identities: Brave release 1.97.56 appears with different product names and versions in the release notes, on Windows, on macOS, in the Linux package and in the NVD CPE dictionary
Versio.io maintains an end-of-life and version database for thousands of products and compares it daily with the software versions detected in customer environments. In doing so, we regularly encounter products and versions that cannot be assigned unambiguously: several spellings of the same product name, version identifiers that differ between the website, the installer and the package manager, release histories without dates and vulnerability advisories that only state "older versions".
 

Quick check: how identifiable is your product?

Tick what already applies to your product. Each point is explained in detail below - the arrow takes you straight to the matching recommendation.
 
The following recommendations are aimed at software vendors. They are deliberately simple, cost little to implement and help everyone who uses or monitors your products:
  • Customers and operators - can see at a glance whether their installation is up to date, still supported and affected by a vulnerability.
  • Vulnerability scanners - can match CVEs precisely to installed versions without false positives or false negatives.
  • End-of-life monitoring - can warn of expiring support in good time.
  • CMDB and asset management - can document versions consistently and in an audit-proof manner.
  • Vendors themselves - receive fewer support requests and fulfil requirements of regulations such as the Cyber Resilience Act (CRA), e.g. on SBOMs, support periods and vulnerability handling.
 

1. Define unique product and vendor names

Before a version can be assigned, it must be clear which product it belongs to. Vendors should therefore define exactly one product name and exactly one vendor name and use them consistently everywhere: on the website, in the installer, in the package metadata, in the version history and in vulnerability advisories.
If the same product appears as "Brave", "Brave-Browser" and "Brave Browser", every tool has to decide whether these are one, two or three products. The same applies to vendor names such as "Example", "Example Ltd" and "Example Software Ltd". Each variant creates an additional entry in inventories, SBOMs and vulnerability databases - and a potential gap when versions and CVEs are matched.
  • ✅ - Define a canonical product name and a canonical vendor name, including spelling, spaces, hyphens and capitalisation.
  • ✅ - Use different product names only for products that are actually different, e.g. a server and its client.
  • ✅ - If a product or vendor is renamed, document the former name and the date of the change in the version history.
  • ❌ - Variants of the same name depending on platform, installer or download page.
 

2. Follow Semantic Versioning

Product versions should follow Semantic Versioning (SemVer) as closely as possible: MAJOR.MINOR.PATCH, e.g. 4.2.1. The MAJOR version is increased for incompatible changes, the MINOR version for new, backwards-compatible functionality and the PATCH version for backwards-compatible bug fixes. Pre-releases and build metadata are appended in the defined way, e.g. 4.3.0-rc.1 or 4.2.1+build.5821.
SemVer is widely used, sortable and can be interpreted by tools without any special knowledge of the product. Its rules make the impact of an update visible in the version itself. If a different scheme is used, such as calendar versioning (e.g. 2026.10.1), it should be documented and applied consistently across all releases.
  • ✅ - Use exactly one technical version scheme per product and document it.
  • ✅ - Always use the same number of components, e.g. 5.0.0 instead of switching between 5, 5.0 and 5.0.0.
  • ✅ - Assign each published build exactly one version, and never reuse a version for a different build.
  • ❌ - Marketing names without a technical version, e.g. "Spring Release" or "2026 R2". If marketing names are required, map each one unambiguously to a technical version.
  • ❌ - Leading zeros, letters as patch level (e.g. 3.1b) and changing separators (e.g. 3.1-2 and 3.1.2 for the same release).
 

3. Publish the version history online

Vendors should publish all product versions and their history online. For each version, the list should contain the exact version identifier - character for character as it appears in the product - and the release date. Ideally, it also includes the end of maintenance (no more bug fixes) and the end of support or end-of-life date (no more security updates), a link to the release notes and a note on which vulnerabilities have been fixed.
  • Completeness - List all versions, including patch releases and hotfixes. Do not remove older versions from the list once they are no longer supported.
  • Unambiguous dates - Use the ISO 8601 date format (YYYY-MM-DD) to avoid confusion between 03/04/2026 and 04/03/2026.
  • Stable URL - Keep the address of the version history stable so that it can be referenced and monitored automatically.
  • Machine-readable format - Additionally provide the version history as JSON or XML, ideally via an API or a feed.
  • CPE mapping - State the Common Platform Enumeration (CPE) identifier of the product in the machine-readable version history, so that vulnerability databases such as the National Vulnerability Database (NVD) can be matched without guesswork.
A machine-readable version history allows customers and tool vendors to process new releases automatically instead of reading them from HTML pages. A simple example:
version-history.jsonjson
{
	"product": "Example Server",
	"vendor": "Example Ltd",
	"cpe": "cpe:2.3:a:example:example_server:*:*:*:*:*:*:*:*",
	"versions": [
		{
			"version": "4.2.1",
			"releaseDate": "2026-09-15",
			"endOfMaintenance": "2027-09-30",
			"endOfSupport": "2028-03-31",
			"releaseNotes": "https://www.example.com/release-notes/4.2.1",
			"fixedVulnerabilities": [ "CVE-2026-12345" ]
		},
		{
			"version": "4.2.0",
			"releaseDate": "2026-07-01",
			"endOfMaintenance": "2027-09-30",
			"endOfSupport": "2028-03-31",
			"releaseNotes": "https://www.example.com/release-notes/4.2.0"
		}
	]
}
 

4. Make the installed product and version queryable

Once a product has been installed, it must be possible to query its product name, vendor name and version using the operating system's package manager or the command line. The values returned must correspond exactly to the published product name, vendor name and version identifier. Only then can an installation be matched to the version history and to vulnerability advisories without manual interpretation.
  • Linux - Register the exact product name, vendor name and version in the package metadata, e.g. in the Name, Vendor and Version fields of an RPM package, queryable via rpm -q or dpkg -s.
  • Windows - Enter the published product name as DisplayName, the vendor name as Publisher and the version as DisplayVersion in the uninstall registry key and in the file version information, or provide them via winget.
  • macOS - Set CFBundleName and CFBundleShortVersionString in Info.plist to the published product name and version; provide Homebrew packages with the same names and version.
  • Command line - Support a --version option that outputs the exact version in a parsable form.
  • Appliances, containers and services - Provide the version via an API endpoint, an SNMP value or an image label, e.g. org.opencontainers.image.version.
Command linebash
$ example-server --version
4.2.1
A typical source of errors is version identifiers that differ depending on where they are read: the website announces version 24.2, the Windows registry shows 24.2.0.1234 and the command line outputs "build 1234". In such cases, each tool has to guess which number is meant. If an internal build number is needed, it should be appended as build metadata (e.g. 24.2.0+1234) and not replace the version.
 

5. Name exact versions in vulnerability advisories

When publishing vulnerabilities, it is essential to name the affected and fixed versions exactly. Vague statements lead to false positives, unnecessary emergency patches and, in the worst case, overlooked vulnerabilities.
Even version ranges such as "4.0.0 to 4.2.0" leave room for interpretation: to evaluate them, the reader has to derive every version in between - or, in the worst case, know every version ever released, including hotfixes and builds that never appeared in a public release list. It is therefore best to list every affected version explicitly.
  • ❌ - "All versions before the latest release", "version 3.x", "older versions" or "contact support for details".
  • ❌ - Version ranges such as "4.0.0 to 4.2.0" or "< 4.2.1", which require knowledge of all versions in between.
  • ✅ - List every affected version explicitly, e.g. "affected: 4.0.0, 4.0.1, 4.1.0, 4.1.1, 4.2.0; fixed in: 4.2.1".
  • ✅ - Name a fixed version for each supported release line, e.g. 3.8.7 and 4.2.1.
  • ✅ - Use the same version identifiers as in the version history and in the installed product.
  • ✅ - Publish advisories in machine-readable form, e.g. as CSAF documents with CPE or package URL (purl) identifiers, and list the affected versions individually in the CVE record.
 

Read more


Talk to me


Matthias Scholze
Matthias Scholze
Chief Technology Officer
P:  +49-30-221986-51
LinkedIn

 
 

Further information

 

We use cookies to ensure that we give you the best experience on our website. Read privacy policies for more information.