Because git describe ignores lightweight tags by default. If you marked a release with a plain git tag v2.4.0, the command may report an older annotated tag or just a commit hash. Create release tags as annotated tags and the version string will reflect them.
What is happening
The git-tag manual states that annotated tags are meant for release, while lightweight tags are meant for private or temporary labels. It adds that for this reason some git commands that name objects, such as git describe, ignore lightweight tags by default.
Many build systems derive their version from git describe. When the release tag is lightweight, the build can silently pick an older tag and append a count of commits since then. Your binary then claims to be a version it is not.
Why this is a security issue, not only a tidiness issue
Version strings are how users, support teams and scanners decide whether a build contains a fix. If a patched release reports itself as the previous version, then:
- A customer may think the fix is missing and ask for an unnecessary re-release.
- A scanner or inventory may match the build against advisories for the older version and raise false findings.
- Worse, a vulnerable build can report a newer version than it truly is if tags were moved carelessly.
Accurate version metadata supports accurate vulnerability matching. Our post on how a tag is not a version covers the related point that a tag name alone is weak evidence.
How to check your own repository
git describe
git describe --tags
git for-each-ref refs/tags --format='%(refname:short) %(objecttype)'
In the last command, the object type column shows tag for annotated tags and commit for lightweight ones. Any release tag showing commit is a candidate to recreate as annotated.
How to fix it
- List your release tags with their object types.
- For each lightweight release tag that has not been widely consumed, create an annotated tag on the same commit with a new message.
- Do not move a tag that others already fetched. Git's documentation advises that if a tag has been published, the sane approach is to use a different name rather than re-tag. See what happens when a git tag moves after you pulled it.
- Add a CI check that fails the release job if the tag is not an annotated object.
Checklist for release tagging
| Step | Why |
|---|---|
| Use annotated tags | Recorded in release tooling and honoured by describe |
| Sign them where you can | Adds who vouched for the commit |
| Never reuse a tag name | Others may already hold the old target |
| Test the version string in CI | Catches a wrong version before it ships |
Quick check
Does git describe tags include lightweight tags?
There is an option to include them, but the default ignores them according to the git documentation. Do not depend on a flag; use annotated release tags.
Can I convert a lightweight tag to annotated?
You can create an annotated tag at the same commit, but if the old name was already published, prefer a new version number over rewriting it.
Sources
Last reviewed: 19 October 2026.