Staying on an old major version can be the right call for a limited time, if that version still receives security fixes, you have a dated plan to move, and you have recorded the decision and who owns it. It is the wrong call when the version is past end of life or when staying is just a way of not deciding.
Define the question
A major version is the first number in a version such as 4.2.1. Under semantic versioning, it changes when backward incompatible changes are introduced. Staying on an older major means you keep running code that the maintainers may still patch, may patch only for critical issues, or may no longer touch at all.
Three tests before you stay
1. Is it still supported? Check the project's published policy. Node.js, for example, states that LTS typically guarantees critical bug fixes for a total of 30 months, and Python describes about five years of support per release with a bugfix phase followed by a security only phase. Other projects publish their own windows. If you cannot find a policy, treat that as a finding.
2. Does it receive security fixes today? Support for bug fixes is not the same as support for security fixes. Look for the latest release date on the line you run, not just the project overall.
3. Can you absorb the next advisory? If a serious flaw is announced next week, can you ship the fix on your current major, or will it only exist on the new one? If only on the new one, staying has a hidden price.
A decision table
| Situation | Reasonable to stay? | Condition |
|---|---|---|
| Old major, still gets security fixes | Yes, short term | Dated migration plan |
| Old major, bugfix only | Risky | Compensating controls, shorter date |
| Old major, past end of life | No | Replace, isolate, or retire |
| Vendor certifies only the old major | Sometimes | Written exception with review date |
| Migration is blocked by an abandoned library | Sometimes | Replacement plan and owner |
What to write down
Keep a short record for each exception: the component, the version, why you are staying, what compensates for the risk, the owner, and the review date. An exception without a review date is just a permanent decision made by default.
Compensating controls that help
- Restrict network exposure of the affected service.
- Add monitoring for the specific vulnerability class.
- Subscribe to the project's security announcements.
- Check whether the vulnerable code path is even reachable in your application.
None of these replaces upgrading. They buy time.
The trap to avoid
The danger is not the old major itself. It is that every month on it raises the cost of leaving, because the gap to the current major widens and more of your other dependencies assume the newer API. A planned stay has an exit. An unplanned one does not.
Safeguard's SBOM and dependency scanning lists direct and transitive packages with their versions, and reachability analysis shows which outdated or vulnerable ones your code actually calls. Autonomous remediation can open fix pull requests; it is off by default and every category starts on Manual. You can try a free scan at gold.safeguard.sh/scan.
Quick check
Can I stay on an old major if there are no known vulnerabilities?
For a limited time, yes, if it is still supported. Absence of known issues in an unsupported version can simply mean nobody is looking or fixing.
Who should approve staying on an old major?
The service owner proposes it and security reviews it. Record both names with the review date.
Sources
- Semantic Versioning 2.0.0
- Node.js releases
- Status of Python versions
- OWASP Top 10:2021, A06 Vulnerable and Outdated Components
Last reviewed: 19 October 2026.