Every estate has one server that cannot be patched, because the application on it will not run on anything newer. An instance you cannot patch needs a smaller attack surface and a firm exit date while the supported replacement gets built.

Name the Constraint
First confirm why the instance cannot receive another supported patch. The release can be past support, the operating system can be incompatible, or an application vendor can block a version change. Write the exact reason and who owns it. “We cannot patch” is not an explanation.
When I ask why an instance cannot be patched, the reason is usually real. Occasionally it is a vendor who closed years ago, which is also real, just less comforting.
Record the current ProductVersion and map it to the official build history. Check whether a relevant security update or eligible ESU path exists for that release. Do not assume the instance is unpatchable because it is old. Verify the actual servicing and licensing options before choosing containment alone.
Give the exception a business owner and an end date. A legacy application can be important, but importance does not make its exposure disappear. The owner needs to accept the temporary controls and fund the exit.
SELECT
@@SERVERNAME AS ConnectedInstance,
SERVERPROPERTY('ProductVersion') AS ProductVersion,
SERVERPROPERTY('Edition') AS Edition,
SERVERPROPERTY('ProductBuildType') AS BuildType;Isolate the Network Around an Instance You Cannot Patch
Place the instance on a network segment that accepts only required application traffic and administration paths. Deny broad workstation and internet access. Document the allowed source, destination, port, and reason for each rule. A rule described only as “SQL access” is too vague for review.
Almost every unpatchable server I have seen was reachable from far more machines than it needed. Who actually has to connect to this instance? Every other path is a door you can close today.
Test the rules from both allowed and denied locations. Confirm that monitoring and backups still work. A firewall policy that cuts off backups creates a different risk. Review DNS aliases and linked servers for hidden routes. An old SQL Server can be exposed through an application server even when it has no public address.
Log connection attempts at the network boundary where your tools support it. Alerts should go to an active team. Isolation is only useful when it remains in place after later network changes.
Use Least Privilege on an Instance You Cannot Patch
Review application accounts, SQL logins, Windows groups, and sysadmin membership. Remove access no longer needed. Give each application only the rights required for its workload. Avoid shared administrative credentials. Use separate identities for backup, monitoring, and application traffic.
Check service accounts and stored credentials. Rotate them through your approved process. A password embedded in a legacy script needs a replacement plan. Do not break a critical process by deleting a credential without testing, but do not leave a broad privilege unexplained.
Limit administrator access to a controlled jump path. Audit changes and failed logins. A dated access review helps show whether the exception is being managed. The goal is to make compromise harder and its signals easier to see.
Least privilege starts with knowing who already has everything.
SELECT
p.name AS login_name,
p.type_desc,
p.is_disabled
FROM sys.server_role_members AS rm
JOIN sys.server_principals AS r ON r.principal_id = rm.role_principal_id
JOIN sys.server_principals AS p ON p.principal_id = rm.member_principal_id
WHERE r.name = 'sysadmin'
ORDER BY p.name;
Remove Unused Features and Paths
Inventory enabled SQL Server features and network protocols. Disable what the application does not use, after testing. Review SQL Server Browser exposure, remote access paths, linked servers, CLR usage, and extended procedures according to the release and workload. Do not copy a generic hardening script into a fragile old instance.
Uninstalling unused client tools or services can reduce surface, but it can also change shared components. Test the exact action on a clone. Keep a rollback plan and backup. A feature that looks idle can support a monthly process nobody remembers.
Document the required features. This list becomes useful when you build the replacement. It separates genuine application dependencies from old defaults.
Watch and Back Up the Instance You Cannot Patch
Verify full, differential, and log backups according to the database recovery model. Test a restore on a separate server or VM. Protect master and msdb so jobs and logins can be rebuilt. Keep installation media and license records where the recovery team can find them.
Monitor service health, failed logins, new accounts, configuration changes, and unusual outbound connections. Keep logs long enough for the security team to investigate an event. Monitoring is a detection control, not a substitute for a missing patch.
Review the restore procedure for the old release. Compatible operating systems, drivers, and installers can become scarce. A backup that cannot be restored onto available hardware is not an adequate recovery plan.
Build the Supported Replacement
Choose a supported SQL Server target and test the application there. Restore a recent database backup, move required logins and jobs, and run critical workflows. Identify deprecated features and driver changes. Engage the application vendor early if certification is the blocker.
A side by side migration gives you a target to validate while the old instance stays isolated. Plan data synchronization and cutover carefully. After a database moves to a newer major engine format, a return to the old engine needs a compatible backup or logical reverse path.
Fund the migration as a project with milestones. A firewall rule is not a reason to delay design work indefinitely. Put dates on test, remediation, cutover, and retirement.
Make the Retirement Date Real
Review the exception for an instance you cannot patch on a fixed schedule. Show remaining blockers, current exposure, backup test date, and progress toward migration. If the date slips, require a new risk decision from the owner. An expired exception should not renew itself silently.
A retirement date with nobody’s name beside it is a wish. Put a name on it.
After cutover, check for lingering connections, jobs, and reports using the old instance. Preserve required data and audit evidence, then stop and retire the instance through change control. Remove its network exceptions and credentials. Update the inventory with the retirement date.
I treat a legacy server like a temporary construction zone. Keep access narrow, keep people informed, and finish the work. A permanent fence around a broken machine is not a plan.
Check the exception after every network or application change. A new integration can reopen access that the original firewall review closed. Require the owner to approve that route and update the retirement plan.
Related reading on this blog: Giving an Application Account Only What It Needs and Maximizing SQL Server Security: Instance Hiding vs SQL Browser Disable.

Containment is not a patch, it is time bought for a dated retirement plan.
Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.





1 Comment. Leave new
I keep getting an error and haven’t been able to find a fix in all of the websites I’ve looked at so far. Can you help me?
I cannot load Security Update for SQL Server 2000 Service Pack 4 (KB948119).
What is this and how to I fix it?
Thanks for your help.