SQL SERVER – FIX – Error – Msg 4928, Level 16, State 1. Cannot Alter Column Because it is ‘Enabled for Replication or Change Data Capture’

A reader wrote to me about a database restored from production into QA. No replication or Change Data Capture there. Every flag they checked came back zero. SQL Server still refused to rename a column, and blamed both. I rebuilt the whole thing on SQL Server 2025. The error turns out to be stranger than it looks.

A padlocked iron gate across a loading bay lit by one amber wall lamp

The Error

EXEC sp_rename 'dbo.Foo.Bar', 'Bar1', 'COLUMN';
Msg 4928, Level 16, State 1
Cannot alter column 'Bar' because it is 'REPLICATED'.

The wording has changed since I first wrote about this. Older versions named both, saying the column was enabled for Replication or Change Data Capture. The current one just says REPLICATED. Shorter, and as you are about to see, still not true.

CDC Marks Your Columns as Replicated

Here is the whole cause, and it is one line. I made a plain database with no replication anywhere near it and turned on Change Data Capture:

EXEC sys.sp_cdc_enable_db;

EXEC sys.sp_cdc_enable_table
     @source_schema = N'dbo',
     @source_name   = N'Foo',
     @role_name     = NULL,
     @supports_net_changes = 0;

Then I looked at the columns:

name   is_replicated
id     1
Bar    1
Baz    1

Every column flagged as replicated. There is no publication on this server. There is no distributor. There is no subscriber. CDC sets is_replicated, because internally it uses the same log reader plumbing that transactional replication uses. The flag is honest about the mechanism and misleading about the cause.

So my reader checked is_replicated, found ones, and reasonably concluded there was replication. There was not. Then they checked is_tracked_by_cdc, found zeroes, and concluded there was no CDC either. Both readings were correct. The trouble was that the two flags had come apart.

The Strangest Part

The error says cannot alter column. So I tried altering the column, expecting to be stopped. With CDC on the table, every one of these worked:

ALTER TABLE dbo.Foo ALTER COLUMN Bar varchar(80);   -- widened, fine
ALTER TABLE dbo.Foo ALTER COLUMN Baz bigint;        -- type changed, fine
ALTER TABLE dbo.Foo DROP COLUMN Baz;                -- dropped, fine
EXEC sp_rename 'dbo.Foo', 'Foo2';                   -- table renamed, fine

I widened it, retyped it, dropped it outright, and renamed the whole table. Then I tried the column rename again, on a column that still existed:

Msg 4928: Cannot alter column 'Bar' because it is 'REPLICATED'.

So CDC will let you delete a tracked column without a word, and will not let you change its name. An error that says cannot alter is raised by the one operation that is not an alter.

There is a logic to it once you stop being annoyed. CDC keeps a capture instance with its own copy of the column list, matched by name. Drop a column and the capture table holds nulls, which is survivable. Rename one and the match breaks, with nothing in CDC to tell you. So it refuses. It is protecting itself rather than you, but it is protecting something real.

Checking All of It at Once

The flags live in three different places and people usually check one. Run all of them:

SELECT name,
       is_cdc_enabled,
       is_published,
       is_merge_published,
       is_subscribed
FROM   sys.databases
WHERE  name = DB_NAME();

SELECT name, is_tracked_by_cdc, is_replicated
FROM   sys.tables
WHERE  is_tracked_by_cdc = 1 OR is_replicated = 1;

SELECT OBJECT_NAME(object_id) AS table_name, name AS column_name, is_replicated
FROM   sys.columns
WHERE  is_replicated = 1;

On my test database with CDC on, is_cdc_enabled came back 1 and everything about publishing came back 0. The table was tracked and replicated, and all three columns replicated. That pattern is what CDC looks like. If the column flags are set and every database flag is clear, your metadata has come apart. That was my reader’s situation.

The Fix

If CDC is genuinely on and you can turn it off, that is all it takes:

EXEC sys.sp_cdc_disable_table
     @source_schema    = N'dbo',
     @source_name      = N'Foo',
     @capture_instance = N'all';

I checked straight afterwards and is_tracked_by_cdc was 0, the count of columns still flagged as replicated was 0, and the rename went through on the next statement. Clean.

Stale flags are a different matter. That happens on a restored copy where the tidying never finished. The trick is to turn CDC on and off again, so SQL Server clears up after itself properly:

USE YourDatabase;
GO
EXEC sys.sp_cdc_enable_db;
GO
EXEC sys.sp_cdc_enable_table
     @source_schema = N'dbo', @source_name = N'Foo',
     @role_name = NULL, @supports_net_changes = 0;
GO
EXEC sys.sp_cdc_disable_table
     @source_schema = N'dbo', @source_name = N'Foo',
     @capture_instance = N'all';
GO
EXEC sys.sp_cdc_disable_db;
GO

That is what worked for my reader. It looks silly, and it is the right shape of silly. A process set those flags and never got to run its own clean-up. So you let it run.

For leftover replication metadata rather than CDC, the equivalent is:

EXEC sp_replicationdboption 'YourDatabase', 'publish', 'false', 1;
EXEC sp_removedbreplication 'YourDatabase';

My reader had already run both. Neither helped, which is what pointed at CDC rather than replication in the first place.

Why This Happens on a Restored Database

Restore a production database somewhere else and the CDC flags travel with it. They are part of the database. Whether CDC keeps running depends on how you restored it.

Use KEEP_CDC and the flags and capture tables come with it. Leave it off and SQL Server is supposed to strip the flags. When that clean-up does not finish, the database says it is tracked while nothing tracks it. Which is exactly a QA copy of production, restored quickly, by someone with no reason to think about CDC at all.

If you refresh QA from production on a schedule, check these three flags at the end of the refresh script. Finding it there costs a minute. Finding it when a developer cannot rename a column costs an afternoon.

Msg 4928 is not a replication problem, it is Change Data Capture wearing replication’s coat.

This post was rewritten in September 2026. It was first published on 24 December 2016.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.

Change Data Capture, SQL Replication, SQL Scripts, SQL Server
Previous Post
SQL SERVER – SqlServerWriter Missing from an Output of VSSadmin List Writers Command
Next Post
SQL SERVER 2016 – Trace Flag 1117 is Discontinued. Use the Options Provided with ALTER DATABASE

Related Posts

1 Comment. Leave new

  • We are getting the same error but its in legacy environment(SQL 2000). Checked that the column which we are trying to update is not a part of replication still we are getting the below error

    Msg 4929, Level 16, State 1, Line 1
    Cannot alter the table ‘xxxxxxx’ because it is being published for replication.

    Can someone please assist here? Thanks

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.