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 inView on GitHub (pinned to e0f6eb3518)
Solutions
- Provide a valid username and password via the Basic auth header for the protected route.
- If using a different identifier field, set 'basic' username field via Auth::basic()->username or the guard config.
- Verify the user exists and the password hash matches using Hash::check.
- 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
- Send valid Basic credentials on auth.basic routes.
- Confirm the configured username field (email vs username).
- Avoid Basic auth for end-user-facing routes; use session or token auth.
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthenticated.
- Auth guard [{$name}] is not defined.
- Auth driver [{$config['driver']}] for guard [{$name}] is not
- Unable to bind custom driver callback
- Authentication user provider [{$driver}] is not defined.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/64ad1f78d364dc71.
Report an issue: GitHub.