laravel/framework · error · UnauthorizedHttpException

Invalid credentials.

Error message

Invalid credentials.

What it means

Thrown by SessionGuard::failedBasicResponse() as a Symfony UnauthorizedHttpException('Basic', ...) when HTTP Basic authentication credentials provided in the request are empty or invalid. It triggers the browser's native 401 WWW-Authenticate: Basic challenge.

Source

Thrown at src/Illuminate/Auth/SessionGuard.php:409

     * @param  \Symfony\Component\HttpFoundation\Request  $request
     * @param  string  $field
     * @return array
     */
    protected function basicCredentials(Request $request, $field)
    {
        return [$field => $request->getUser(), 'password' => $request->getPassword()];
    }

    /**
     * Get the response for basic authentication.
     *
     * @return void
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    protected function failedBasicResponse()
    {
        throw new UnauthorizedHttpException('Basic', 'Invalid credentials.');
    }

    /**
     * Attempt to authenticate a user using the given credentials.
     *
     * @param  array  $credentials
     * @param  bool  $remember
     * @return bool
     */
    public function attempt(#[\SensitiveParameter] array $credentials = [], $remember = false)
    {
        return $this->timebox->call(function ($timebox) use ($credentials, $remember) {
            $this->fireAttemptEvent($credentials, $remember);

            $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

            // If an implementation of UserInterface was returned, we'll ask the provider
            // to validate the user against the given credentials, and if they are in

View on GitHub (pinned to e0f6eb3518)

Solutions

  1. Provide a valid username and password via the Basic auth header for the protected route.
  2. If using a different identifier field, set 'basic' username field via Auth::basic()->username or the guard config.
  3. Verify the user exists and the password hash matches using Hash::check.
  4. Switch the route to a session-based 'auth' middleware if stateless Basic is not desired.

Example fix

// before — no credentials
$response = Http::get('https://app.test/api/protected'); // UnauthorizedHttpException

// after — supply Basic credentials
$response = Http::withBasicAuth('user@example.com', 'secret')->get('https://app.test/api/protected');
Defensive patterns

Strategy: try-catch

Validate before calling

// PHP — validate basic credentials before the middleware check
[$user, $pass] = [$request->getUser(), $request->getPassword()];
if ($user === null || $pass === null || ! Auth::validate([$basicField ?? 'email' => $user, 'password' => $pass])) {
    return response()->json(['message' => 'Invalid credentials.'], 401);
}

Type guard

// HTTP-level guard: ensure Authorization header present and decodable
function hasBasicCredentials(\Illuminate\Http\Request $r): bool {
    return $r->getUser() !== null && $r->getPassword() !== null;
}

Try / catch

try {
    // route with auth.basic middleware
} catch (\Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException $e) {
    return response()->json(['message' => 'Invalid credentials.'], 401);
}

Prevention

When it happens

Trigger: A route guarded by the 'auth.basic' middleware receives a request with missing/incorrect Authorization: Basic <base64(user:pass)> header, or credentials that fail the provider's retrieval+hash check.

Common situations: Stateless HTTP Basic-protected endpoints (e.g. internal admin tools) hit without credentials; typos in the username/password; cached wrong credentials in the browser; stateful sessions bypassed because auth.basic always re-checks the header.

Understand the failure class

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/64ad1f78d364dc71. Report an issue: GitHub.