MeWrite Docs

Laravel: Specified key was too long; max key length is 767 bytes

Laravelマイグレーション時にキー長エラーが発生する原因と解決策

概要

Laravel 5.4以降で新規プロジェクトを作成し、php artisan migrateを実行すると発生するエラー。MySQL 5.7.7未満またはMariaDB 10.2.2未満で、デフォルトの文字列長が長すぎることが原因です。

エラーメッセージ

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`))

原因

  1. 文字セットの変更: Laravel 5.4からデフォルト文字セットがutf8mb4に変更された
  2. インデックス長の制限: MySQL 5.7.7未満では、インデックスの最大長が767バイト
  3. 計算: utf8mb4は1文字4バイト × 255文字 = 1020バイト(767を超過)

なぜ utf8mb4 なのか

utf8mb4は絵文字を含む全てのUnicode文字を保存できます。utf8(3バイト)では絵文字が保存できません。

解決策

1. AppServiceProviderでデフォルト文字列長を設定(推奨)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Schema::defaultStringLength(191);
    }
}

なぜ191文字?

  • 191 × 4バイト = 764バイト(767バイト以内)

2. MySQLをアップグレード

MySQL 5.7.7以上またはMariaDB 10.2.2以上にアップグレードすると、インデックスの最大長が3072バイトに拡張されます。

1
2
3
4
5
# MySQLバージョン確認
mysql -V

# または MySQL内で
SELECT VERSION();

3. config/database.phpで文字セットを変更(非推奨)

1
2
3
4
5
// config/database.php
'mysql' => [
    'charset' => 'utf8',      // utf8mb4 から変更
    'collation' => 'utf8_unicode_ci',  // utf8mb4_unicode_ci から変更
],

注意: この方法だと絵文字が保存できなくなります。

4. マイグレーションで個別に長さを指定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// database/migrations/xxxx_create_users_table.php
public function up(): void
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email', 191)->unique();  // 191文字に制限
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}

Laravel バージョン別の対応

バージョンデフォルト対応
5.3以前utf8対応不要
5.4〜10.xutf8mb4解決策1を適用
11.x以降utf8mb4解決策1を適用

よくある間違い

  • 既存のマイグレーションファイルを編集せずにdefaultStringLengthだけ設定
  • migrate:fresh後に再度エラーが出る(AppServiceProviderの設定漏れ)
  • 本番環境のみMySQL古いバージョンで気づかない

参考リンク

関連エラー

関連エラー

PHP の他のエラー

最終更新: 2025-12-11