Published Updated

How to Fix the "Specified Key Was Too Long" Error in Laravel (3 Solutions)

MySQL "Specified key was too long" error message in the Laravel console during migrations
Table of Contents

    ⚙️ 2026 Note: if you are using MySQL 8 or MariaDB 10.5+ with Laravel 9 or later, you should no longer see this error on new projects: the default charset is utf8mb4 with innodb_default_row_format=DYNAMIC, and indexes now support up to 3072 bytes. This article is still useful if you are working with legacy databases, older servers, or shared hosting environments still running MySQL 5.6/5.7 or MariaDB 10.1.

    How many times have you installed a new Laravel project only to run your migrations and be greeted with an error in the console:

    [Illuminate\Database\QueryException]
    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))
    
    [PDOException]
    SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
    

    There are 3 ways to fix it:

    Solution 1

    If you are using MySQL older than 5.7.7 or MariaDB older than 10.2.2, simply upgrade to the latest stable release and you will never see this problem again.

    Solution 2

    If you can’t upgrade the server but you do administer it, go after the cause: the InnoDB row format. Tables using the COMPACT or REDUNDANT row format (the Antelope file format) only allow 767-byte index keys; with DYNAMIC or COMPRESSED (the Barracuda file format) and innodb_large_prefix enabled, the limit goes up to 3072 bytes. MySQL 5.7 enables all of that by default; on MySQL 5.6 you have to turn it on yourself in my.cnf and restart:

    [mysqld]
    innodb_file_format = Barracuda
    innodb_file_per_table = 1
    innodb_large_prefix = 1
    

    The tables also need to be created with ROW_FORMAT=DYNAMIC. Laravel appends the engine value from config/database.php to the CREATE TABLE statement, so you can force it from there:

    'mysql' => [
        ...
        'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
    ]
    

    Note that setting just 'engine' => 'InnoDB' fixes nothing. InnoDB has been MySQL’s default engine since 5.5; the 767-byte limit depends on the row format, not the engine.

    Solution 3

    If you can’t touch the server configuration (shared hosting, for example), add the following line to app/Providers/AppServiceProvider.php:

    use Illuminate\Support\Facades\Schema;
    
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
    

    Why does this error occur?

    Starting with Laravel 5.4, the default database character set was changed to utf8mb4, which includes support for storing emojis. In utf8mb4 each character can take up to 4 bytes, so an indexed VARCHAR(255), like the unique email on the users table, needs up to 1020 bytes and blows past the 767 limit. At 191 characters (764 bytes) it fits, which is why Solution 3 works. It only affects servers where that limit is still in place: MySQL older than 5.7.7, MariaDB older than 10.2.2, or tables still on the COMPACT row format.

    Found it useful? Share it

    Found it useful? Get the next one by email

    Once a week: what breaks when you upgrade, AI for developers and what I'm building, with sources. No spam.

    By subscribing you accept our privacy policy.

    Search

    Tags

    AI Migration PHP Laravel JavaScript Tutorial Web Development Security Upgrade Best Practices TypeScript OpenAI SEO Backend Claude