There is one change in Laravel 5.8 that is not mentioned in the official Upgrade Guide but caused me problems – I couldn’t create a foreign key migration, and spent half-hour until found out the reasons. So I want to share, maybe you will encounter the same thing.
My Situation Example and Error
While working on one project, I’ve created a simple table transaction_types:
php artisan make:migration create_transaction_types_table
And added just one new string() field:
Schema::create('transactions_types', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
And then tried to create a migration for transactions table with a foreign key, with same syntax I used to do all the time:
php artisan make:migration create_transactions_table
Migration file content:
Schema::create('transactions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('transaction_type_id')->unsigned();
$table->foreign('transaction_type_id')->references('id')->on('transactions_types');
$table->decimal('amount');
$table->timestamps();
});
And here’s what happened when running php artisan migrate:

As usual, the error “cannot add foreign key constraint” doesn’t give much details so I was just guessing, what could go wrong:
- Typo in table name? Double-checked, nope.
- Too long foreign key name? (should be up to 64 characters) Doesn’t seem so.
- Mismatch in foreign key field types? Hmmm, then I noticed something…
Look closer at what Laravel is generating when doing php artisan make:migration command:
Schema::create('transactions_types', function (Blueprint $table) {
$table->bigIncrements('id');
// ...
bigIncrements. BIG increments. And then, of course, if you’re doing a foreign key from just “unsigned integer” type (as I always did my whole life), it fails. Type mismatch. Obviously.
How to Fix
Well, it’s easy. There are two ways to make it work:
- Either change original migration from bigIncrements() to just increments();
- Or in your foreign key column do bigInteger() instead of integer().
The choice is yours.
Why Am I so Angry About It
Simple – this change wasn’t mentioned anywhere in 5.8 changes.
- Official 5.8 Upgrade guide? Nope. Well, ok, it doesn’t affect the project during upgrade specifically, so maybe it’s fair.
- Laravel News official blog: main announcement by Paul Redmond? Not a word.
- Same blog: maybe one of the articles about 5.8? Nothing there either.
So, it makes me think that probably it’s only me with this problem, and everyone else will actually notice that migrations are being generated with bigIncrements().
After some googling, I’ve found one Reddit thread and one Stackoverflow post about it. That’s it.
Oh, and, of course, it was mentioned and discussed in the official Github repository of Laravel, back in November 2018:
- [Laravel Ideas Proposal] Switch the default increments() to a bigint #1384
- Commit to stub: use bigIncrements
- Discussion after someone got same error as me: SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint #27717
Don’t get me wrong, I’m not against that change to bigIncrements(). I’m just angry about how it was (NOT) communicated. Probably only a bunch of people participating in internal Github communications actually knew about this change.
P.S. Oh, by the way, default users table migration also comes with bigIncrements():
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
So whenever you create new fields with foreign key to users, don’t forget to use bigInteger().
Just before i saw your tweet I upgraded a package to 5.8 where i have a user_id foreign key in a migration, then i tested it within a new laravel5.8 project and i ran the migrate command but nothing happened it worked, I saw the tweet and I went back and checked again but still no errors, “binIncrements” id against “unsignedInteger” user_id, maybe somehow it fixed
I had no problems, I always use bigIncrements, but thank you very much for the advice Povilas.
Took me a while to figure it out too!
I guess we should be start using bigIncrements then….
Nice one!
Thanks for the heads up
Funny enough. I went for an interview and part I was to develop and app and that was the first time I was working with Laravel 5.8 . I had same error as you and that really wasted my time trying to debug. I think that change should have been communicated.
That can definitely catch you off-guard if you’re not looking out for it.
Based on this post I’ve just made a PR to the upgrade guide so, hopefully, it won’t be an issue for others going forward. https://github.com/laravel/docs/pull/5082
[…] I wrote this just as somewhere to have a link to this brilliant article by Povilas on Laravel […]
Shouldn’t the foreign key be specified as a “unsignedBigInteger” since “bigIncrements” reflects a column of type UNSIGNED BIGINT?
Yes, unsignedBigInteger(field), or bigInteger(field)->unsigned()
Nice article!
Yesterday took me like 2-3 hours to figure out this. I just started working with laravel 2 weeks ago and I thought I was doing something else wrong..
Hi! It’s nice article! But I didn’t solve this error.
Illuminate\Database\QueryException : SQLSTATE[HY000]: General error: 1005 Ca
n’t create table `dbstudent`.`#sql-11c8_1f` (errno: 150 “Foreign key constraint
is incorrectly formed”) (SQL: alter table `transactions` add constraint `transac
tions_transaction_type_id_foreign` foreign key (`transaction_type_id`) reference
s `transactions_types` (`id`))
at C:\xampp\htdocs\students\vendor\laravel\framework\src\Illuminate\Database\C
onnection.php:664
660| // If an exception occurs when attempting to run a query, we’ll
format the error
661| // message to include the bindings with SQL, which will make th
is exception a
662| // lot more helpful to the developer instead of just the databa
se’s errors.
663| catch (Exception $e) {
> 664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|
Exception trace:
1 PDOException::(“SQLSTATE[HY000]: General error: 1005 Can’t create table `d
bstudent`.`#sql-11c8_1f` (errno: 150 “Foreign key constraint is incorrectly form
ed”)”)
C:\xampp\htdocs\students\vendor\laravel\framework\src\Illuminate\Database\
Connection.php:458
2 PDOStatement::execute()
C:\xampp\htdocs\students\vendor\laravel\framework\src\Illuminate\Database\
Connection.php:458
Please use the argument -v to see more details.
Scripts:
public function up()
{
Schema::create(‘transactions’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->bigInteger(‘transaction_type_id’)->unsigned();
$table->foreign(‘transaction_type_id’)->references(‘id’)->on(‘transactions_types’);
$table->decimal(‘amount’);
$table->timestamps();
});
}
public function up()
{
Schema::create(‘transaction_types’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->string(‘name’);
$table->timestamps();
});
}
I think you made a typo, transactions_types vs transaction_types
Great post. I was about to pull my hairs out when I saw this post. And to think I’m bald.
For me need to change both for work. bigIncrements to increments and bigInterger to integer()->usigned()
Thanks Povilas. There is not many resources out there about this issue. Thanks for sharing
Yes I have faced the same problem when I was creating a migration file which has a foreign key on references
another table .I have fixed this problem after thirty or thirty five minutes later.
Thanks for sharing.
keep it on …
Thank you for the solution concerning the the foreign key migration problem, it really helped me.
Thanks!! – was pulling hair out – a little embarrassed I did not notice the data type change, but still, if the laravel team is going to make datatype changes it would be nice if they warn people
Thanks i had several tries but your did the charm
What the heck. Iam currently trying to fix my massive project but never got a idea. I just removed this foreign key line and ignored it but it had some very weird aftereffects.
I tried a new installation after almost 1 year and luckily the first thing i noticed in migrations is the change from increments to bigIncrements. I googled it (yah i am lazy enough not to go through the docs!) and the first link landed me here. Saved me some debugging time i think! But i think that anyone who looks first into migrations file will always notice the change and it follows naturally to find out about it!
Thank you so much! I was just faced with the same problem.
Fortunately I found this article and it went well.
Thanks man, big Help!
Thanks lot..it helps me I am facing the foreign key error…
The more popular Laravel gets, the less they seem to care about communication. And bigIncrements for an ID in a table? Come on … how many applications are you going to build that will have 9,223,372,036,854,775,807 records in a particular table? Maybe google has a table like that (but I doubt it). Tables that big should be split into something else. Right now, I just use integerIncrements(‘id’), but I’m thinking of overriding their stuff. Same thing goes for a default varchar of 255 — it’s their arbitrary decision, although I realize there should be a default. I think one should have some idea of what kind of data is going into the database. Especially an email — 255 chars for that? Gimme a break. Use the defaults when it makes sense, but use something else if you know the data.