On this page
Why it happens
Error 207 is a name resolution failure, not a syntax failure. The query is grammatically valid, so SQL Server accepts its shape, but when it tries to bind each column reference to a real column in the tables in scope it cannot find one that matches. The message names the offending identifier: Invalid column name 'emial'. That name is your fastest clue, because it is exactly the text SQL Server could not resolve.
The most common cause is a simple typo, such as emial for email. Close behind are qualifier problems: the column exists but lives in a different table in the join, or you referenced it without a prefix and no table in scope actually has it. Because the error is severity 16, it is a normal, catchable error that you fix by correcting the statement, not a server problem.
A subtler cause is scope. A column alias you define in the SELECT list is not visible in the WHERE clause, GROUP BY, or elsewhere in the same SELECT, so referencing it there raises 207. The same happens after a column is renamed or dropped, or when application code runs against a database where the expected schema change has not been deployed yet.
Examples
A misspelled column name
CREATE TABLE dbo.Users (
id INT PRIMARY KEY,
email NVARCHAR(255)
);
-- 'emial' is a typo for 'email'
SELECT id, emial FROM dbo.Users;
Msg 207, Level 16, State 1, Line 7 Invalid column name 'emial'.
Using a SELECT alias in WHERE
-- full_name is defined in the SELECT list, but the alias
-- is not visible in WHERE, so 207 is raised.
SELECT first_name + ' ' + last_name AS full_name
FROM dbo.Users
WHERE full_name LIKE 'A%';
Msg 207, Level 16, State 1, Line 5 Invalid column name 'full_name'.
Column belongs to a different table in the join
-- CustomerId lives on Orders, not Users, and the
-- unqualified reference cannot be resolved.
SELECT u.id, CustomerId
FROM dbo.Users AS u
JOIN dbo.Orders AS o ON o.UserId = u.id;
Msg 207, Level 16, State 1, Line 3 Invalid column name 'CustomerId'.
How to fix it
Check the spelling against the table definition
Confirm the real column name before you guess. Query sys.columns or run sp_help on the table, then correct the identifier to match exactly.
-- List the real column names for the table
SELECT name
FROM sys.columns
WHERE object_id = OBJECT_ID('dbo.Users');
-- Or inspect the whole table
EXEC sp_help 'dbo.Users';
-- Then use the correct name
SELECT id, email FROM dbo.Users;
Qualify the column with its table or alias
In a join, prefix every column with the table or alias that owns it. This resolves 207 when the column exists but on a different table, and it removes ambiguity for the reader.
SELECT u.id, o.CustomerId
FROM dbo.Users AS u
JOIN dbo.Orders AS o ON o.UserId = u.id;
Do not reference a SELECT alias in WHERE or GROUP BY
Aliases from the SELECT list are not available in WHERE or GROUP BY, so repeat the expression, or wrap the query in a subquery or CTE (or use CROSS APPLY) so the computed value has a real name you can filter on.
-- Repeat the expression in WHERE
SELECT first_name + ' ' + last_name AS full_name
FROM dbo.Users
WHERE first_name + ' ' + last_name LIKE 'A%';
-- Or expose the alias through a CTE
WITH named AS (
SELECT first_name + ' ' + last_name AS full_name
FROM dbo.Users
)
SELECT full_name FROM named WHERE full_name LIKE 'A%';
Refresh IntelliSense after a schema change
If the column really was renamed, added, or dropped, stale IntelliSense can flag a valid name or hide a change. Refresh the local cache in SSMS with Edit > IntelliSense > Refresh Local Cache (Ctrl+Shift+R) and make sure you are connected to the database where the schema change was deployed.
-- Confirm the column now exists in this database
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Users' AND COLUMN_NAME = 'email';
How to prevent it
Use consistent, predictable naming across your schema so a column is easy to spell from memory, and always qualify columns with a table alias in any query that touches more than one table. That single habit prevents both the typo class and the wrong-table class of 207. For the fundamentals, see the SQL syntax guide.
Deploy schema changes before the code that depends on them, and keep environments in sync so a column your query expects actually exists where the query runs. When you are learning the language, working through the SQL tutorial builds the muscle memory for naming and qualifying columns correctly.
Common questions
Why can I not use a SELECT alias in the WHERE clause?
SQL Server evaluates WHERE before the SELECT list, so a column alias you define in SELECT does not exist yet when WHERE runs. Referencing it there raises error 207. Repeat the underlying expression in WHERE, or wrap the query in a subquery or CTE so the computed value has a real name you can filter on.
What is the difference between error 207 and error 208?
Error 207 is an invalid column name: the table is found but one of its columns cannot be resolved. Error 208 is an invalid object name: the table or view itself cannot be found. In short, 207 is about a column and 208 is about the object that would contain it. See the guide on error 208 at https://codewithsql.com/errors/208.
How do I find the correct column name?
Query sys.columns for the table, or run sp_help on it, to list every real column name. Then correct your statement to match the spelling exactly, and qualify the column with its table alias if the query joins more than one table.