netbirdio/netbird · error
validate access token failed with error: %v
Error message
validate access token failed with error: %v
What it means
Raised by DeviceAuthorizationFlow.WaitToken after a token was successfully obtained, when validateTokenAudience rejects it (device_flow.go:302-305). validateTokenAudience (client/internal/auth/util.go:32) decodes the JWT payload without signature verification and requires the aud claim (string or array) to match providerConfig.Audience. A mismatch means the IdP issued a token for a different API/audience than the one NetBird management requested.
Source
Thrown at client/internal/auth/device_flow.go:304
log.Infof("device flow: IdP requested slow_down, polling interval increased to %s", interval)
continue
}
return TokenInfo{}, errors.New(tokenResponse.ErrorDescription)
}
tokenInfo := TokenInfo{
AccessToken: tokenResponse.AccessToken,
TokenType: tokenResponse.TokenType,
RefreshToken: tokenResponse.RefreshToken,
IDToken: tokenResponse.IDToken,
ExpiresIn: tokenResponse.ExpiresIn,
UseIDToken: d.providerConfig.UseIDToken,
}
err = validateTokenAudience(tokenInfo.GetTokenToUse(), d.providerConfig.Audience)
if err != nil {
return TokenInfo{}, fmt.Errorf("validate access token failed with error: %v", err)
}
log.Infof("device flow: user authorization confirmed after %d polls in %s", polls, time.Since(start).Round(time.Second))
return tokenInfo, err
}
}
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Compare the aud claim of the returned token (decode the JWT payload) with the Audience configured in NetBird management - they must match exactly
- On Azure AD, verify the app registration's 'Application ID URI' and that the NetBird service app has the user-scope consent for that API
- If the IdP cannot issue JWT access tokens with the right audience, enable UseIDToken in the management IdP config so the (always JWT) ID token is validated and used instead
- After changing the IdP config on management, restart the login flow; cached flow state can keep requesting the old audience
Defensive patterns
Strategy: validation
Validate before calling
// Compare the token's aud claim with the configured audience before handing it on
func tokenAudienceMatches(token, want string) bool {
parts := strings.Split(token, ".")
if len(parts) != 3 {
return false
}
claims, err := base64.RawURLEncoding.DecodeString(parts[1])
if err != nil {
return false
}
var c struct {
Aud any `json:"aud"`
}
if json.Unmarshal(claims, &c) != nil {
return false
}
switch aud := c.Aud.(type) {
case string:
return aud == want
case []any:
for _, a := range aud {
if s, ok := a.(string); ok && s == want {
return true
}
}
}
return false
} Try / catch
token, err := flow.WaitToken(ctx, info)
if err != nil {
if strings.Contains(err.Error(), "validate access token failed") {
// configuration-level mismatch: point the administrator at the IdP audience settings
}
} Prevention
- Make the IdP API identifier (audience) in NetBird management exactly match the IdP application's identifier URI
- For Azure AD, ensure the app registration exposes an Application ID URI and the consent is granted
- Prefer enabling UseIDToken when the IdP cannot issue audience-carrying JWT access tokens
When it happens
Trigger: The token's aud claim differs from the Audience configured in the NetBird IdP settings. Concrete producers: Azure AD returning an opaque or v1-audience access token when the API audience (api://...) is not registered/granted, Auth0 audience parameter not honored because the API is not configured, or management's configured Audience not matching the IdP application's identifier URI.
Common situations: Azure AD tenants where the NetBird app registration exposes api://<client-id> but admin consent or the audience grant is missing; Auth0 where the API identifier in NetBird management differs by a trailing slash or version from the API's identifier; switching an account's IdP configuration while old clients still hold the previous audience.
Related errors
- authentication failed: invalid access token - %w
- required token field audience is absent
- token received is empty
- token is not a well-formed JWT
- failed reading access token response body with error: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/85e88c239ecc4622.
Report an issue: GitHub.