Tony Wilhelm has amassed over two decades of experience working with databases and computers. His
expertise in SQL server dates back to 1999, showcasing his extensive knowledge in the field. Throughout his career,
Tony has held various roles, including DBA, developer, and manager, in both large and small companies spanning
multiple industries.
Currently, Tony serves as a senior consultant and SQL Server technical lead for the Data Intelligence division at
Moser Consulting. In this role, he brings his wealth of experience to the table, providing valuable insights and
guidance to drive the implementation of effective solutions.
Speaking Engagements
I'm just starting out on my speaking journey, and am looking forward to adding
more to this list in the future. I also have a public Sessionize profile.
Same server, same GUI, same new-user wizard — and yet some databases auto-check db_owner on you and some don't. Here's the SID mismatch actually causing it.
A client asked me a version of this question recently: "when creating new SQL users with SSMS, they're getting added to the db_owner role automatically?" My first instinct was to say no — SSMS maps new users to public by default, full stop. That's still true. But if you're staring at the User Mapping screen watching that db_owner box check itself before you've touched anything, something else is going on, and it's not random.
What made this case interesting is that it wasn't happening on every database — just some of them, with no obvious pattern at first glance. Chasing that inconsistency down landed on a root cause that shows up constantly after restores and migrations: a binary SID that never got rewritten. Worth a full write-up, because "it works on some databases and not others" is exactly the kind of bug report that makes DBAs assume they're losing their minds.
A note on using sa: a few examples below reassign ownership to [sa] for simplicity. sa is a built-in account with unrestricted sysadmin rights, so making it a database owner widens your attack surface more than the fix actually requires, and plenty of shops disable it outright for exactly that reason. Follow your organization's security policy for database ownership rather than defaulting to sa.
Ruling Out the Obvious Suspects
Before you go digging into SIDs, check the two things that actually are documented SSMS behavior. First: a database with a blank or invalid owner — usually from a restore or attach where the original creator's login no longer exists — makes the User Mapping GUI glitch and pre-check db_owner for anyone you try to map. The fix is a one-liner:
USE [YourDatabaseName];
GO
ALTER AUTHORIZATION ON DATABASE::[YourDatabaseName] TO [sa];
GO
Second: check the model database. Anything configured there gets inherited by every new database on the instance, db_owner defaults included. If someone made a "helpful" change to model six months ago, this is where it comes back to bite you.
In this case, one orphaned database turned up — fixed, confirmed, done. But the client came back with: other databases were still doing it, and not consistently.
Why It's Inconsistent Even on Databases You Own
Here's where it got genuinely strange. The client owned nearly every database on the instance under their own Windows login — one exception was owned by a disabled sa account. That one behaved fine. The rest, all owned by the same account, split roughly down the middle between "behaves" and "checks the box." Same owner, same login, same SSMS build. Three mechanics explain the split:
1AD group ownership vs. an individual login. If a database was created or restored under an AD group context (DOMAIN\Domain_DBAs) rather than one person's account, SSMS can't cleanly resolve individual permissions against a group owner and misbehaves.
2SIDs out of sync between server and database metadata. The owner's display name matches everywhere in the GUI, but the binary SID backing that name doesn't — a leftover from a migration or restore. This turned out to be the actual cause here.
3Contained database settings. A contained database bypasses the instance-level security architecture entirely, which changes how ownership resolves and can produce the same symptom for unrelated reasons.
The Smoking Gun
Every database triggering the bug traced back to option 2: the database-level dbo user still carried the binary SID from the server it was originally restored or attached from. SSMS shows the correct display name, because it resolves the SID against Active Directory, not against the local instance — but underneath, master.sys.databases.owner_sid and sys.database_principals.sid (for the dbo row) don't agree. The user-mapping logic hits that mismatch and fails open, pre-checking db_owner as a safety default.
You can confirm it across every database on the instance in one pass:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
USE [' + d.name + N'];
SELECT DB_NAME() AS DatabaseName,
CASE
WHEN sp.sid IS NULL THEN ''MISSING dbo PRINCIPAL''
WHEN sl.is_disabled = 1 THEN ''OWNER IS DISABLED''
WHEN d.owner_sid <> sp.sid THEN ''MISMATCH: Master SID <> Database SID''
ELSE ''VALID''
END AS Status,
d.owner_sid AS MasterSid,
sp.sid AS DatabaseSid;'
FROM master.sys.databases d
LEFT JOIN sys.server_principals sl ON sl.sid = d.owner_sid
WHERE d.database_id > 4;
EXEC sp_executesql @sql;
Once you've got a list of MISMATCH databases, the fix isn't reassigning ownership once — it's cycling it. Handing ownership to sa clears the stale metadata, and handing it right back rewrites a fresh, correct SID under the current server's context:
USE [YourDatabaseName];
GO
ALTER AUTHORIZATION ON DATABASE::[YourDatabaseName] TO [sa];
GO
ALTER AUTHORIZATION ON DATABASE::[YourDatabaseName] TO [DOMAIN\YourLogin];
GO
Run the validation query again afterward. MISMATCH rows should convert to VALID. Anything still flagged as OWNER IS DISABLED is a database legitimately owned by a disabled sa account — normal in locked-down environments, and not the bug you're chasing.
Reading the Validation Report
Status
What It Means
VALID
Owner SID matches on both ends. SSMS will behave normally.
MISMATCH
The bug. Server and database-level SIDs disagree — usually a leftover from a restore or attach. Cycle ownership through sa to fix.
MISSING dbo PRINCIPAL
No valid owner at all. Assign one explicitly with ALTER AUTHORIZATION.
OWNER IS DISABLED
Database is owned by a disabled login (often sa). Perfectly legal, and won't trigger the bug.
The practical takeaway: add ALTER AUTHORIZATION ON DATABASE::[DBName] TO [ValidOwner]; to every post-restore and post-migration checklist, right next to the usual orphaned-user cleanup. A stale SID is a lot like a stale timing chain on a bike — it won't announce itself until you're already relying on it, and by then you're troubleshooting under load instead of at your own pace.
BEGIN TRAN Four days, two Southwest connections each way, one community data conference, an allegedly world-record Walmart, and a 4am alarm Thursday morning. The usual. Time to SELECT * FROM adventure WHERE city = 'Albany'.
Thursday · Aug 6
Wheels Up from Indy
Travel Day
WN IND → MDW → ALB
✈Up at 4am, coffee before the car, hour drive to IND, 6:45am Southwest departure. Connect through Midway, land in Albany. No stored procedures required — just a boarding pass and questionable sleep math.
ðŠĶOakwood Cemetery, Troy, NY — paying respects to Uncle Sam (Samuel Wilson, 1766–1854), the Troy meatpacker whose name became the one. Worth the detour.
ð―#SQLFamily Dinner with Jason & Sheila Romans, Kristyna Ferris, Andy Yun, and Deborah Melkin — MOSU. Fair warning: index talk may occur between courses. If you don't already follow these folks, fix that: The Data Shepherd · Data on Wheels · SQLBek · Deb the DBA
Friday · Aug 7
Exploring the Capital Region
Pre-Con Day & Shenanigans
☕Coffee & Breakfast:Uncommon Grounds for coffee & bagels — been a tradition since 2024. Jason also put Bitchin' Donuts on the radar this time. That's worth investigating.
ðWorld's Largest Walmart?? Apparently this is a thing in the Albany area. And… what on earth is a Cartalator? A cart elevator? A shopping cart escalator? Either way, it's a full table scan of the grocery section. Investigation required. Photographic evidence will be obtained.
ð―Lunch with the Romans' — Latham Bagel Shop. It's always somewhere good.
ðSpeaker Dinner — the night before I'm on stage, so naturally I'm spending it at dinner with the speaker crew, organizers, and volunteers. Kristyna Ferris and Chris Hyde are wrapping up their full-day pre-con Modern Data Warehousing with Microsoft Fabric — expect them to arrive opinionated about whether a Lakehouse is just a data warehouse with a branding problem.
Free to attend, put on by the community, for the community. SQL Server, data engineering, analytics, AI — real sessions from practitioners who actually do the work. This is what conferences looked like before they cost $2,000 and had a keynote from a vendor you've never heard of.
ð Massry School of Business, UAlbanyð August 8, 2026ðĨ Capacity: 300ð In-PersonðĪ My session: Intro to PowerShell with dbatools — because your DBA toolkit deserves a throttle, not just a mouse
ðģBreakfast — Duck Donuts — made-to-order donuts before the drive to the airport. Priorities.
ðLunch with Jason & Sheila Romans — Dinosaur Bar-B-Que, Troy. Last meal before the flights home. If you're in the area Sunday, pull up a chair — #SQLFamily welcome.
✈The first leg out of Albany is shared with Jason & Sheila Romans. Southwest passengers on this flight: you have been warned. This crew may be loud, caffeinated, running hot from 48 hours of data conference opinions, and still debating whether NULL equals NULL.
ð Connecting through Midway and wheels down in Indy.
ðThank you to the Capital Area SQL Server User Group and Edward Pollack for organizing Day of Data Albany. Running a free community conference is a lot of invisible work — grateful it exists.
Sep 14 – 22, 2026 · Jax Data User Group + Cartel Baggers Key West Getaway
LAFAYETTE→JACKSONVILLE→MIAMI→KEY WESTand back againLAFAYETTE
BEGIN TRAN
What started out as a road trip to Key West quickly turned into another excuse to spend time with #SQLFamily — Jason & Sheila Romans (The Data Shepherd) and Jeff Taylor (jefftaylor.io). Ten days, ~3,000 combined miles split across a Santa Cruz towing an MC-10 trailer and one Harley-Davidson V-Rod riding shotgun, eighteen dealer stops, a Wednesday-night user group presentation, and a Florida Keys bike show with a tricycle race in it somewhere. This is the trip in one page — the four full write-ups are linked below.