Error 2628: Finding the Value That Would Be Truncated

Error 2628 tells you which column was too small and shows the start of the value that did not fit. Use that to fix the input, not to switch the warning off.

Unbranded cigar cutter with a fitting slim cigar and an oversized cigar outside

The nightly import that said almost nothing

Many of us have lived this. A nightly import fails with “String or binary data would be truncated.” The table has forty columns. Nobody knows which one is too small, so someone spends the morning guessing.

Modern SQL Server answers that question for you. Error 2628 names the table and the column, and it quotes the beginning of the offending value. Let me show it. The demo creates a database and drops it at the end. First, two settings that decide which message you get.

USE master;
DROP DATABASE IF EXISTS SqlAuthorityDemo;
GO
CREATE DATABASE SqlAuthorityDemo;
GO
USE SqlAuthorityDemo;
GO
SELECT compatibility_level
FROM sys.databases
WHERE database_id = DB_ID();

SELECT name, value
FROM sys.database_scoped_configurations
WHERE name = N'VERBOSE_TRUNCATION_WARNINGS';

On my server the compatibility level is 170 and VERBOSE_TRUNCATION_WARNINGS is 1. That combination gives the detailed message. Switch the setting off, as I do near the end, and you get the short one.

Trigger the error and read it

The table has one varchar(5) column. I try to insert the word toolong, which is 7 characters. The CATCH block returns the error number and prints the message.

CREATE TABLE dbo.TruncDemo (ValueText varchar(5));
GO
BEGIN TRY
    INSERT dbo.TruncDemo (ValueText) VALUES ('toolong');
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() AS error_number;
    PRINT ERROR_MESSAGE();
END CATCH;

SELECT COUNT_BIG(*) AS stored_rows FROM dbo.TruncDemo;

The error number is 2628 and the table is still empty, so the statement was rejected, not half done. The message in the Messages tab names the table, the column ValueText, and the truncated value ‘toolo’. That is the first five characters of what you tried to store.

One warning. The message can contain part of the input. If that input is a name or an account number, it may end up in a log that many people can read. Protect those logs.

Find every bad value before you insert

The error shows only the first offender. In a real import you want all of them at once. Load the data into a staging table first, then compare each value with the target column size. I use DATALENGTH, because LEN ignores trailing spaces.

DROP TABLE IF EXISTS #Stage;

CREATE TABLE #Stage (Id int PRIMARY KEY, ValueText varchar(100));
INSERT #Stage (Id, ValueText) VALUES (1, 'short'), (2, 'toolong'), (3, 'abc   ');

SELECT Id, ValueText,
       LEN(ValueText) AS trimmed_length,
       DATALENGTH(ValueText) AS source_bytes,
       COL_LENGTH(N'dbo.TruncDemo', N'ValueText') AS target_bytes
FROM #Stage
WHERE DATALENGTH(ValueText) > COL_LENGTH(N'dbo.TruncDemo', N'ValueText')
ORDER BY Id;

Two rows come back. Row 2 is obvious: 7 bytes against 5. Row 3 is the sneaky one. LEN says 3, but the value has three trailing spaces, so DATALENGTH says 6. Remember that COL_LENGTH reports bytes, and it returns NULL if the table or column name is wrong. An empty work list can mean a clean batch, or it can mean a typo.

My filter is deliberately strict. It flags the padded row even though, as you will see below, SQL Server accepts that value. Strict is the safe side for a boundary check.

Handle a truncation error the right way

Do not hide the problem

Casting to a shorter type looks like an easy escape. It is not.

SELECT TRY_CONVERT(varchar(5), 'toolong') AS shortened_value;

You get toolo, with no error and no NULL. The value is silently cut, and nobody is told. For an identifier whose last characters matter, that is worse than a failed import.

Truncation error with rejected value and measured source lengths
All results in order: compatibility level, the setting, error 2628, zero stored rows, the two flagged values, and the shortened value.

Two things that surprise people

First, trailing spaces. The padded value from the staging table has 6 bytes, but it fits in the column.

INSERT dbo.TruncDemo (ValueText) VALUES ('abc   ');

SELECT ValueText, DATALENGTH(ValueText) AS stored_bytes
FROM dbo.TruncDemo;

No error. SQL Server keeps five bytes: abc and two spaces. The extra trailing spaces are cut quietly. That is why my strict filter is a policy, not a prediction.

Second, the short message. The setting I checked at the start can be turned off for a database. Then you get the old message, with no table, column or value in it.

ALTER DATABASE SCOPED CONFIGURATION SET VERBOSE_TRUNCATION_WARNINGS = OFF;
GO
BEGIN TRY
    INSERT dbo.TruncDemo (ValueText) VALUES ('toolong');
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() AS error_number;
    PRINT ERROR_MESSAGE();
END CATCH;
GO
ALTER DATABASE SCOPED CONFIGURATION SET VERBOSE_TRUNCATION_WARNINGS = ON;

The error number is now 8152, and the message is only “String or binary data would be truncated.” That is the one that cost the team a morning. Leave the setting on, fix the input, or talk to the people who call this code about a larger column.

DROP TABLE IF EXISTS #Stage;
DROP TABLE IF EXISTS dbo.TruncDemo;
GO
USE master;
DROP DATABASE IF EXISTS SqlAuthorityDemo;

Next time an import fails, read the error before you start guessing.

A truncation error is not noise, it is a boundary telling you where it was crossed.

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


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

Best Practices, SQL Error Messages, SQL Server
Previous Post
SQL SERVER – Fix – Error 15240, Severity: 16, State: 2 – Cannot write into file
Next Post
SQL SERVER – AlwaysOn AG (Availability Group) and TDE Error – Please Create a Master Key

Related Posts

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.