Specified Key Was Too Long: The Real Fix, Not the One-Liner Everyone Copies
You run your first migration on a fresh Laravel install and get this back.
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))
Every guide I have seen points you to the same one-line fix, and it does work. But almost none of them mention what that fix actually does to the rest of your database. I want to cover both the fix and the part that gets left out.
Why this happens
Laravel uses the utf8mb4 character set by default, which supports the full range of Unicode, emojis included. In utf8mb4, each character can take up to four bytes. A standard VARCHAR(255) column with a unique index needs up to 1020 bytes just for that index, since 255 characters times 4 bytes each gets you there fast.
Older MySQL versions, and MariaDB by default, cap a single index key at 767 bytes. Your column's index blows straight past that limit, and MySQL refuses to create it. This only shows up on MySQL older than 5.7.7 or on MariaDB running with certain default settings. Modern MySQL 8 raises this limit significantly for standard InnoDB tables, so a lot of people simply stop seeing this error the moment they upgrade their database version.
The fix everyone copies
In app/Providers/AppServiceProvider.php, inside the boot() method:
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
This tells Laravel to cap the default length of any string column at 191 characters instead of 255, whenever a migration does not explicitly set a length. At 191 characters times 4 bytes, the index stays at 764 bytes, just under the 767 byte ceiling. Run your migrations again and the error disappears.
The part most guides skip: this changes every string column, not just the one with the problem
Here is what I think deserves more attention. Schema::defaultStringLength(191) is a global setting. It does not just apply to the one column that triggered the error. Every migration you write from that point forward, using a plain $table->string('column_name') with no explicit length, gets capped at 191 characters instead of Laravel's normal default of 255.
That is fine for something like an email address or a short slug. It is a real problem for a column that legitimately needs more room, a blog post title, a short description field, a product name that can run long. Copy this fix in blindly, and six months later you might be debugging a mysterious truncated title with no idea why, since nothing in that specific migration ever mentioned a length limit at all.
A better fix for a specific column
If only one or two columns are actually causing the problem, set the length explicitly on just those columns instead of changing the global default.
$table->string('email', 191)->unique();
This solves the exact same indexing problem without quietly capping every other string column in your entire application. I would reach for this first, and only use the global defaultStringLength call if you are dealing with an older codebase that already has this pattern scattered everywhere and a full audit is not realistic right now.
Does this still happen on MySQL 8 in 2026
Mostly no, for a simple single-column unique index like the one in the example above. But I would not assume you are completely safe just because you are on a current MySQL version. Compound indexes across multiple utf8mb4 columns can still add up past the byte limit, even on modern MySQL, since the same four-bytes-per-character math still applies once you are combining several indexed string columns together. If you are building a multi-column unique index and see this same error on a database you assumed was too modern to hit it, check the combined byte length of every column in that index, not just the one you added most recently.
FAQ
Do I need to run this fix on every Laravel project?
No. If your database is MySQL 8 or a recent MariaDB version and you are only using simple, single-column indexes, you likely will never see this error at all. Only add the fix if you actually hit it.
Will this fix break my existing data?
It does not touch existing data directly, but a global default of 191 characters applies to any new migration column that does not specify a length, so double check any new columns you add afterward are not silently getting truncated to a length you did not intend.
Should I just upgrade my database instead of patching Laravel?
If that is an option for your hosting setup, upgrading to a current MySQL or MariaDB version is the more durable fix, since it removes the underlying limit rather than working around it. Not everyone controls their database version, especially on shared or managed hosting, which is why the Laravel-side fix exists in the first place.
What happens if I set the length too short for real data?
MySQL will either truncate the value or reject the insert, depending on your SQL mode settings. Either outcome is worse than the original migration error, since it fails silently or loses data instead of stopping you at migration time with a clear message.
Does this affect Laravel's built-in authentication tables?
Yes, this is exactly where most people first hit it, since the default users migration includes a unique index on the email column, which is the single most common trigger for this error on a fresh install.
Bottom line
The one-line global fix works, but it is not free. It quietly shrinks every unspecified string column in your app to 191 characters, not just the one causing the error. Set an explicit length on the specific column that needs it instead, and save the global default for a codebase where doing that everywhere is not realistic.
Sources: Laravel official documentation, Migrations; MySQL 8.0 Reference Manual, InnoDB Limits. Verified against official documentation on September 18, 2026.
Comments 0
Be the first to comment.
Leave a comment