Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

elle3141's avatar

Error message when trying to register a user - "The email has already been taken"

I have been following the following tutorial: https://www.toptal.com/laravel/restful-laravel-api-tutorial, however I have an issue.

I am up to the stage where I run the following curl code in my terminal:

curl -X POST https://myapp.jdoe.blah.test/api/register \
 -H "Accept: application/json" \
 -H "Content-Type: application/json" \
 -d '{"name": "Elle", "email": "[email protected]", "password": "total123456", "password_confirmation": "total123456"}'

According to the tutorial, I should receive the following information in this form, of course with my details instead of his:

{
    "data": {
        "api_token":"0syHnl0Y9jOIfszq11EC2CBQwCfObmvscrZYo5o2ilZPnohvndH797nDNyAT",
        "created_at": "2017-06-20 21:17:15",
        "email": "[email protected]",
        "id": 51,
        "name": "John",
        "updated_at": "2017-06-20 21:17:15"
    }
}

However instead I get the following message:

{"message":"The given data was invalid.","errors":{"email":["The email has already been taken."]}}

I checked in my users table and the user was successfully registered, but why am I receiving this message? Also, in the users table, the api_token field is empty.

The code in RegisterController is:

<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use \Illuminate\Http\Request;

class RegisterController extends Controller
{
    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }

    protected function registered(Request $request, $user)
    {
        $user->generateToken();

        return response()->json(['data' => $user->toArray()], 201);
    }
}

The code in api.php:

Route::post('/register', 'Auth\RegisterController@register');

The code in User.php:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Http\Request;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function generateToken()
    {
        $this->api_token = str_random(60);
        $this->save();

        return $this->api_token;
    }
}

I am new to Laravel, so if you need me to provide code for something else, please say and I will.

Thanks in advance :).

0 likes
4 replies
Atef95's avatar

"The email has already been taken" the error is obvious.. in your backend validation you set unique email for every user..

  'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],

elle3141's avatar

Thank you for your reply. I thought that saying email addresses must be unique means that two users cannot have the same email address. My point is, in my curl I use an email address which was NOT already in the users table in order to register a new user. Then the user is added to the users table but I am not receiving the new user's information as a data object, rather I receive the error to say that the email address has already been taken, when it has not.

How can I change this to view the user object like in the tutorial?

Snapey's avatar

You are correct in that the unique rule prevents two users having the same name. Validation in Laravel is very robust so the only conclusion is that you do indeed already have a user record in the database with this email

The registered function is only called after creating a user

Please or to participate in this conversation.