The installer said success, the ticket is closed, and the server is still on the old build. Checking that a patch really installed takes three pieces of evidence: the engine version, Setup’s summary and the startup log.

Capture the Before Build
Before Setup starts, connect to the exact instance you plan to patch. Save ProductVersion, ProductUpdateLevel, ProductBuildType, machine name, and capture time. A host can run multiple SQL Server instances, and an availability group listener can point to a different replica after failover. Identify the actual target.
Map the full version to the official build history. Record the target build for the CU or GDR you selected. Without an expected result, “version changed” is a weak final check. A successful patch must reach the approved build, not just any later number.
Keep the before query in the change ticket. It also helps when Setup says an update is not applicable. The current branch or edition can explain that result.
SELECT
@@SERVERNAME AS ConnectedInstance,
SERVERPROPERTY('MachineName') AS MachineName,
SERVERPROPERTY('ProductVersion') AS ProductVersion,
SERVERPROPERTY('ProductUpdateLevel') AS UpdateLevel,
SERVERPROPERTY('ProductBuildType') AS BuildType;Read the Setup Summary
SQL Server Setup writes a Summary.txt file and time stamped run folders under the Setup Bootstrap Log directory. Find the folder that matches the patch attempt. Read the overall result and the result for each targeted feature. Do not stop at the first line that says success.
A Database Engine component can succeed while another installed component fails. Setup can also report a restart requirement. Save the summary and any relevant Detail.txt or feature log. This is the installer’s account of what happened, not yet proof that the engine is healthy.
If Setup failed, look for the failing feature and the first meaningful error. Preserve logs before rerunning. A second attempt can create another folder and make the original failure harder to reconstruct.
Query the Running Engine Again When Checking That a Patch Really Installed
After the required restart, reconnect to the instance and run the same version query. Compare the complete ProductVersion with the approved target. ProductUpdateLevel can still show the same CU label after a later GDR on that baseline, so the full string matters.
I trust the running engine over every other source. A green installer window has been wrong before. The engine version is what is actually running.
Confirm the connection target. Query @@SERVERNAME and MachineName with the build. A client alias or availability listener can mislead you. For a rolling patch, connect to each replica instance directly. Do not accept the primary’s build as evidence for every secondary.
If the build is unchanged, stop the rollout. Check Setup’s package selection, target instance, component result, and restart state. An installer exit code alone cannot settle the discrepancy.
SELECT
@@SERVERNAME AS ConnectedInstance,
SERVERPROPERTY('MachineName') AS MachineName,
SERVERPROPERTY('ProductVersion') AS RunningBuild,
SERVERPROPERTY('ProductUpdateLevel') AS UpdateLabel;
Inspect the Startup Error Log for Checking That a Patch Really Installed
SQL Server writes its version and startup information to the error log when the service starts. Find the startup entry for the service restart after patching. Check that it names the expected build and that database recovery completed without new errors. The error log can reveal a failure that a version query alone misses.
Use the current error log and the correct instance. An old archived log can show yesterday’s build. Note the restart time and compare it with the patch timeline. A patch that installed files but left the service running from an old process needs a restart and another check.
The version line is useful evidence, but it is not the whole health check. Read nearby recovery, script upgrade, and service messages. Investigate new warnings rather than declaring success from one matching string.
Check Services and Databases
Confirm SQL Server Agent and any required components started. Check user databases are online. Verify availability group synchronization, replication, or log shipping when the instance uses them. A running Database Engine can still have a broken dependent service.
Run a small application smoke test with the real connection path. Test a login, a representative read, and an approved write path where the application owner can do so safely. Review important Agent jobs after the window. An update is operationally complete only when the workload can use the instance.
Check the first scheduled backup after patching. A paused job or changed replica preference can leave a recovery gap. Include that check in the ticket instead of assuming the old schedule resumed itself.
SELECT
name,
state_desc
FROM sys.databases
WHERE database_id > 4
ORDER BY name;Resolve Conflicting Evidence While Checking That a Patch Really Installed
If Setup reports success but ProductVersion is wrong, verify the instance and package before doing anything else. If the build is right but Setup shows a failed feature, investigate that feature. If the version and summary look good but the error log shows failed recovery, stop application release and address the recovery problem.
I trust the running engine over every document when the two disagree. A spreadsheet cannot restart, and SERVERPROPERTY cannot guess.
When the three sources disagree, which one do you believe? The running engine, every time, and then you find out why the other two said something different.
Treat the three sources as different witnesses. Setup describes the installation action. SERVERPROPERTY describes the running Database Engine. The error log describes startup and recovery. Their agreement gives confidence. Their disagreement is the work.
Keep the timestamps with each source. A version query taken before a restart should not be compared with a startup line from a later attempt as if they were simultaneous. A clean timeline makes troubleshooting faster.
Close With a Reproducible Record
Save the package identity, before and after builds, setup summary, error log excerpt, application result, and backup result. Update the server inventory. If a replica remains behind, record it as an open action with an owner. Do not let a green ticket hide partial patching.
Review the result of checking that a patch really installed before moving to the next production server. A small unexplained difference on the first server is a reason to pause the group. The purpose of staged rollout is to learn before repeating a problem.
I like a simple final sentence in the change record: which instance runs which full build, and which checks passed. That is the evidence another DBA needs tomorrow.
Run the same version query from a fresh connection after the restart. A query window left open across maintenance can confuse the timeline. Save the new connection target and capture time with the result.
Related reading on this blog: How to Check Your SQL Server Version, Edition and Patch Level and Reading the SQL Server Error Log Properly.

A patch is not installed because Setup closed, it is installed when the running service and its logs agree.
Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.





2 Comments. Leave new
Brent added this yesterday:
https://www.brentozar.com/archive/2015/05/announcing-sqlserverupdates-com/
I believe its going to be maintained, so it’s probably handy for the future.
So true!