netbirdio/netbird · error
authentication failed: %s
Error message
authentication failed: %s
What it means
The IdP redirected back to the local callback with the RFC 6749 error parameter set and an error_description present. This is the provider's own refusal of the authorization request, surfaced verbatim: for example 'access_denied' with a consent message, 'invalid_scope', or a tenant policy explanation from Azure AD / Auth0 / Keycloak.
Source
Thrown at client/internal/auth/pkce_flow.go:262
}
renderPKCEFlowTmpl(w, nil)
tokenChan <- token
})
server.Handler = mux
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
errChan <- err
}
}
func (p *PKCEAuthorizationFlow) handleRequest(req *http.Request) (*oauth2.Token, error) {
query := req.URL.Query()
if authError := query.Get(queryError); authError != "" {
authErrorDesc := query.Get(queryErrorDesc)
if authErrorDesc != "" {
return nil, fmt.Errorf("authentication failed: %s", authErrorDesc)
}
return nil, fmt.Errorf("authentication failed: %s", authError)
}
// Prevent timing attacks on the state
if state := query.Get(queryState); subtle.ConstantTimeCompare([]byte(p.state), []byte(state)) == 0 {
return nil, fmt.Errorf("authentication failed: Invalid state")
}
code := query.Get(queryCode)
if code == "" {
return nil, fmt.Errorf("authentication failed: missing code")
}
exchangeStart := time.Now()
token, err := p.oAuthConfig.Exchange(
req.Context(),
code,View on GitHub (pinned to 93e97f4bf1)
Solutions
- Read the description text - it is the IdP's verbatim explanation and points at the exact consent or policy problem.
- Retry the login and complete the consent step; if consent was denied by policy, an IdP tenant admin must grant admin consent for the requested scopes.
- Ask the NetBird administrator to verify the IdP application's API permissions and scopes match the PKCE provider configuration.
- If a conditional-access or MFA policy blocks the client, satisfy the policy (compliant device, approved network) or have it relaxed for this application.
Defensive patterns
Strategy: try-catch
Try / catch
_, err := flow.WaitToken(ctx, info)
if err != nil && strings.Contains(err.Error(), "authentication failed:") {
// err.Error() embeds the IdP's verbatim error_description;
// surface it to the user and map known codes (access_denied, invalid_scope)
// to remediation prompts instead of retrying blindly
} Prevention
- Pre-grant admin consent for all requested scopes (openid, offline_access, profile, email) in the IdP tenant.
- Keep the scopes configured in NetBird's IdP settings within what the IdP application exposes.
- Review conditional-access policies that silently deny non-compliant clients before rolling out logins.
When it happens
Trigger: Callback query contains a non-empty error and a non-empty error_description: the user denied the consent prompt, a requested scope is not granted to the IdP application, conditional-access or MFA policy blocked the sign-in, or the application is misconfigured for the authorization-code grant.
Common situations: User cancels the consent screen; IdP app lacks admin consent for scopes such as offline_access or openid; tenant administrators disabled user consent; conditional access requires a compliant or domain-joined device; scope names in management's IdP config do not match what the app exposes.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- PKCE authorization flow failed: %v
- failed reading access token response body with error: %v
- access token response returned code: %s
- parsing token response failed with error: %v
- validate access token failed with error: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/8096d775b4a6db4d.
Report an issue: GitHub.