{"id":108153,"date":"2026-01-12T15:07:00","date_gmt":"2026-01-12T15:07:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=108153"},"modified":"2026-02-19T19:29:18","modified_gmt":"2026-02-19T19:29:18","slug":"common-sql-server-problems-invalid-length","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/common-sql-server-problems-invalid-length\/","title":{"rendered":"How to fix the Invalid Length error in SQL Server"},"content":{"rendered":"\n<p>This is another part in my <a href=\"https:\/\/www.red-gate.com\/simple-talk\/collections\/common-issues-in-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">series<\/a> designed to offer guidance around common issues in <a href=\"https:\/\/www.microsoft.com\/en-gb\/sql-server\/sql-server-downloads\" target=\"_blank\" rel=\"noreferrer noopener\">SQL Server<\/a>. Today, let\u2019s talk about the all-too-common error: invalid length.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-the-invalid-length-error-in-sql-server\">What Is the Invalid Length Error in SQL Server?<\/h2>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >Msg 537, Level 16, State 3\nInvalid length parameter passed to the LEFT or SUBSTRING function.<\/pre><\/div>\n\n\n\n<p>The invalid length error, as shown above, occurs when you have incorrect or unexpected input to a string <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/sql-server-functions-the-basics\/\" target=\"_blank\" rel=\"noreferrer noopener\">function<\/a>. For example:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >DECLARE @FirstName nvarchar(32) = N'frank';\nSELECT LEFT(@FirstName, -1);<\/pre><\/div>\n\n\n\n<p>While it\u2019s unlikely you\u2019d <em>intentionally<\/em> pass a negative value here, the desired substring often comes from some other calculation. For example, you might assume that a full name always has a space, but that\u2019s not always true:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >DECLARE @FullName nvarchar(32) = N'Madonna';\nSELECT LEFT(@FullName, CHARINDEX(N' ', @FullName)-1);\n<\/pre><\/div>\n\n\n\n<p>Despite the text of the error message, this is not isolated to the <code>LEFT<\/code> and <code>SUBSTRING<\/code> functions. It can be triggered by other functions, such as <code>RIGHT<\/code>, which may make it harder to spot the problem in the code. Imagine being told the error message, then being handed this code, which doesn\u2019t contain <code>LEFT<\/code> or <code>SUBSTRING<\/code>:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT RIGHT(N'Aaron', -1);<\/pre><\/div>\n\n\n\n<p>Still, those are easy to spot, because the -1 gives a clue. What about a more complex expression that is dependent on the data? Let\u2019s say you are using <code>LEFT<\/code> and <code>SUBSTRING<\/code> and other string functions to split a string, a pattern I\u2019ve seen all too often on Stack Overflow (even in the age of <code>STRING_SPLIT<\/code>):<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT t.val,\n       P1 = LEFT(val, CHARINDEX(N'-', val) - 1),\n       P2 = SUBSTRING(val, CHARINDEX(N'-', val)+1, LEN(val) \n            - CHARINDEX(N'-', REVERSE(val)) - CHARINDEX(N'-', val)),\n       P3 = REVERSE(LEFT(REVERSE(val), CHARINDEX(N'-', REVERSE(val)) - 1))\n  FROM (SELECT N'SAM-134-226' AS val) AS t;<\/pre><\/div>\n\n\n\n<p>This is more complex than I would write it, but it works fine \u2013 for certain definitions of \u201cfine\u201d \u2013 until <code>val<\/code> contains fewer than two hyphens (try with <code>'SAM-134'<\/code> or just <code>'SAM'<\/code>). When you have to troubleshoot such an expression, it can be daunting.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-to-fix-the-invalid-length-error-in-sql-server\">How to Fix the Invalid Length Error in SQL Server<\/h2>\n\n\n\n<p>The fix here is usually to add a <code>WHERE<\/code> clause, but the error can also occur even though you have explicitly filtered out values that you know will break your expression &#8211; for example, if you have:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT sub = LEFT(col, CHARINDEX(N'x', col)-1)\n  FROM \u2026\n WHERE col LIKE N'%x%';<\/pre><\/div>\n\n\n\n<p>It may not happen in such a simple query but, in more complex cases, SQL Server might still try to evaluate the expression in the <code>SELECT<\/code> list on all rows, before filtering out the non-qualifying rows via the <code>WHERE<\/code> clause. I have talked about this at length in several Stack Overflow answers:<\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/stackoverflow.com\/a\/21316088\/61305\" target=\"_blank\" rel=\"noreferrer noopener\">Why would YEAR fail with a conversion error from a Date?<\/a><br><br><\/li>\n\n\n\n<li><a href=\"https:\/\/stackoverflow.com\/a\/14421590\/61305\" target=\"_blank\" rel=\"noreferrer noopener\">How to convert varchar to date only when it contains a valid date?<\/a><br><br><\/li>\n\n\n\n<li><a href=\"https:\/\/stackoverflow.com\/a\/12305930\/61305\" target=\"_blank\" rel=\"noreferrer noopener\">MSSQL cast( [varcharColumn] to int) in SELECT gets executed before WHERE clause filters out bad values<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n<p>It can make for convoluted code, but one way to avoid this scenario is to force evaluation of the condition using <code>CASE<\/code> or <code>IIF<\/code>. For example:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT sub = CASE WHEN col LIKE N'%x%' THEN LEFT(col, CHARINDEX(N'x', col)-1) END\n  FROM \u2026\n WHERE col LIKE N'%x%';<\/pre><\/div>\n\n\n\n<p>A more self-documenting way would be:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT sub = CASE WHEN CHARINDEX(N'x', col) &gt; 0 THEN LEFT(col, CHARINDEX(N'x', col)-1) END\n  FROM \u2026\n WHERE col LIKE N'%x%';<\/pre><\/div>\n\n\n\n<p>You don\u2019t need to provide an <code>ELSE<\/code> in either of these scenarios, because the rows that yield <code>NULL<\/code> will ultimately get filtered out anyway.<\/p>\n\n\n\n<p>You can also do something tricky to yield <code>NULL<\/code> when the <code>CHARINDEX<\/code> might be negative, as long as the input string cannot be longer than 255 characters:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT sub = LEFT(col, TRY_CONVERT(tinyint, CHARINDEX(N'x', col)-1))\n  FROM \u2026\n WHERE col LIKE N'%x%';\n<\/pre><\/div>\n\n\n\n<p>Trying to convert to a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/guidelines-for-choosing-data-types\/\" target=\"_blank\" rel=\"noreferrer noopener\">tinyint<\/a> will yield <code>NULL<\/code> when the outcome is negative, since tinyint is constrained to numbers between 0 and 255. However, as mentioned, this has limitations that make it brittle, and is less self-documenting than a <code>CASE<\/code> expression.<\/p>\n\n\n\n<p>If your query is a lot more complex or you have multiple <a href=\"https:\/\/www.red-gate.com\/simple-talk\/featured\/using-regex-in-sql-server-2025-complete-guide\/\" target=\"_blank\" rel=\"noreferrer noopener\">expressions<\/a>, or you still can\u2019t get the filter to apply before SQL Server attempts evaluation, you may want to simply materialize the results into a table before attempting <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/robyn-pages-sql-server-string-manipulation-workbench\/\" target=\"_blank\" rel=\"noreferrer noopener\">string manipulation<\/a>. For example:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT col \n  INTO #x\n  FROM \u2026\n WHERE col LIKE N'%x%';\n\n\/* Now we know all values meet the criteria *\/\nSELECT LEFT(col, CHARINDEX(N'x', col)-1)\n  FROM #x;<\/pre><\/div>\n\n\n\n<p>As an aside, there are other functions where you might <em>expect<\/em> passing a negative length would yield this same error message, but SQL Server more gracefully returns <code>NULL<\/code> instead:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \" >SELECT STUFF(N'Aaron', 1, -1, N'foo');\nSELECT REPLICATE(N'Aaron', -1);<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-final-thoughts-amp-key-takeaways\">Final Thoughts &amp; Key Takeaways<\/h2>\n\n\n\n<p>Always code defensively. Users, bots, and QA engineers are going to come up with plenty of edge cases, sometimes on purpose \u2013 try to think like them. <\/p>\n\n\n\n<p>Someone might inadvertently add a space to their last name, e.g.\u00a0O&#8217; Brien\u00a0or\u00a0D&#8217; Agostino. Or they might legitimately have spaces in their first or last name, e.g.\u00a0De Wayne van der Wal. Or go by a single name only, like Madonna or {insert the \u201cartist formerly known as Prince\u201d emoji here}. <\/p>\n\n\n\n<p>So don&#8217;t, for example, search for the first space and assume there will only be one &#8211; or that there will be one at all.<\/p>\n\n\n\n<section id=\"my-first-block-block_b08dd2d2ba70d9a87380b3a4438a44dd\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">The fast and easy way to write, format and debug SQL<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Save time and effort with the original SQL code completion tool, SQL Prompt &#8211; loved by the SQL Server community for nearly 20 years.                                    <\/div>\n            <\/div>\n                            <a href=\"https:\/\/www.red-gate.com\/products\/sql-prompt\/\" class=\"btn btn--secondary btn--lg\">Learn more &amp; try for free<\/a>\n                    <\/div>\n    <\/div>\n<\/section>","protected":false},"excerpt":{"rendered":"<p>Learn why SQL Server throws the invalid length error in functions like LEFT, SUBSTRING, and RIGHT, and discover practical fixes to prevent it.&hellip;<\/p>\n","protected":false},"author":341115,"featured_media":108154,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143523,53,143524],"tags":[159371,4150,4151],"coauthors":[158980],"class_list":["post-108153","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-databases","category-featured","category-sql-server","tag-common-issues-in-sql-server","tag-sql","tag-sql-server"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/108153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/341115"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=108153"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/108153\/revisions"}],"predecessor-version":[{"id":108500,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/108153\/revisions\/108500"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/108154"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=108153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=108153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=108153"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=108153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}