Ffile2fix
Sign in Get started

How to fix #1071 Specified key was too long; max key length is 767

#1071 - Specified key was too long; max key length is 767 bytes

An index on a text column would exceed the storage engine's maximum key size. With utf8mb4 each character can take 4 bytes, so a VARCHAR(255) index needs 1020 bytes, which is over the 767-byte limit of older InnoDB row formats (or 1000 bytes for MyISAM).

Also appears as: ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes · SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (Laravel migration) · ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes (MyISAM)

Common causes

  • MySQL 5.6 / MariaDB 10.1 or older, where the InnoDB index limit is 767 bytes
  • Tables using COMPACT or REDUNDANT row format instead of DYNAMIC
  • MyISAM tables, which cap keys at 1000 bytes
  • Laravel's default string length of 255 combined with utf8mb4
  • Composite indexes whose combined columns exceed 3072 bytes even on MySQL 8

How to fix it

  1. Check your server version. Run SELECT VERSION();. MySQL 5.7.7+ and MariaDB 10.2.2+ use DYNAMIC row format and a 3072-byte limit by default, so the 767 error mostly means an older server or an old table.
  2. Laravel: limit default string length. In AppServiceProvider::boot() call Schema::defaultStringLength(191); so VARCHAR columns are 191 characters (764 bytes), then re-run migrations.
  3. Shorten the indexed column. Change VARCHAR(255) to VARCHAR(191) on indexed utf8mb4 columns if values never exceed 191 characters (emails, slugs usually don't).
  4. Use a prefix index. Index only the first characters, e.g. INDEX(url(191)). Note a prefix index cannot enforce full-column UNIQUE constraints.
  5. Switch to DYNAMIC row format and InnoDB. Run ALTER TABLE t ENGINE=InnoDB ROW_FORMAT=DYNAMIC; on old tables so they get the 3072-byte limit (requires innodb_file_per_table and Barracuda on MySQL 5.6).
  6. Upgrade the database server. Where possible move to MySQL 8.0+ or MariaDB 10.6+, which removes this limit for normal VARCHAR(255) utf8mb4 indexes.

Laravel app/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

public function boot(): void
{
    Schema::defaultStringLength(191);
}

How to stop it happening again

  • Run a current MySQL 8 or MariaDB 10.6+ server
  • Size indexed VARCHAR columns to the real maximum length of the data
  • Use InnoDB with DYNAMIC row format for all tables

Frequently asked questions

Why 191?

767 bytes divided by 4 bytes per utf8mb4 character is 191.75, so 191 characters is the longest fully indexable VARCHAR under the old limit.

Should I switch to utf8 instead of utf8mb4 to avoid this?

No. Legacy utf8 (utf8mb3) can't store emoji and is deprecated. Keep utf8mb4 and fix the index length instead.

Why does the message say 3072 bytes on MySQL 8?

That's the limit for DYNAMIC InnoDB tables. You hit it with composite indexes or very long VARCHARs; reduce the indexed columns or use prefix lengths.