netbirdio/netbird · error
Run `netbird profile list --show-id` to see IDs, then selec
Error message
Run `netbird profile list --show-id` to see IDs, then select by ID prefix: netbird profile select|remove <id-prefix>
What it means
Returned by the same callback handler when extractUserIDFromToken comes back empty after a successful token exchange. extractUserIDFromToken (auth.go:142) requires an id_token in the token response, verifies its signature and audience via provider.Verifier with ClientID, then reads the 'sub' claim; failure at any step (missing id_token, failed verification, unparseable claims) yields '' and the handler answers 401 'Failed to validate token'.
Source
Thrown at client/cmd/profile.go:322
return nil
}
// wrapAmbiguityError turns the daemon's gRPC InvalidArgument errors
// (which carry the resolver's message verbatim) into CLI-friendly text
// that points the user at --show-id.
func wrapAmbiguityError(err error, handle string) error {
if err == nil {
return nil
}
st, ok := gstatus.FromError(err)
if !ok {
return err
}
switch st.Code() {
case codes.InvalidArgument:
msg := st.Message()
if strings.Contains(msg, "ambiguous") {
return errors.New(msg + "\nRun `netbird profile list --show-id` to see IDs, then select by ID prefix:\n netbird profile select|remove <id-prefix>")
}
case codes.NotFound:
return fmt.Errorf("profile %q not found", handle)
}
return err
}
// addProfileOnDaemon issues the AddProfile RPC on an existing daemon client
// and returns the new profile's ID. It is the single entry point for profile
// creation, shared by `netbird profile add` and the `netbird up --profile
// <name>` auto-create path.
func addProfileOnDaemon(ctx context.Context, client proto.DaemonServiceClient, profileName, username string) (profilemanager.ID, error) {
resp, err := client.AddProfile(ctx, &proto.AddProfileRequest{
ProfileName: profileName,
Username: username,
})
if err != nil {
return "", fmt.Errorf("add profile failed: %w", err)View on GitHub (pinned to 93e97f4bf1)
Solutions
- Check the management log immediately before the 401: 'No id_token in OIDC response' means the flow must request the openid scope; 'Failed to verify ID token' with 'invalid audience' means ClientID mismatch; 'Failed to extract claims' points to a malformed token.
- Confirm the authorization request includes scope 'openid' so the IdP returns an id_token.
- Verify the ClientID used for the proxy OIDC config matches the audience (aud) claim of the issued ID token.
- If keys rotate frequently, retry the login flow once so provider discovery and verification use the same JWKS set.
Example fix
// before: authorize URL built without the openid scope, IdP returns no id_token
authURL := oauth2Config.AuthCodeURL(state, oauth2.SetAuthURLParam("scope", "email profile"))
// after: include openid so extractUserIDFromToken gets an id_token with a sub claim
authURL := oauth2Config.AuthCodeURL(state, oauth2.SetAuthURLParam("scope", "openid email profile")) Defensive patterns
Strategy: validation
Validate before calling
// Before redirecting users to the IdP, assert the flow will yield an id_token
// with a subject: request the openid scope and sanity-check the client ID.
if !strings.Contains(authorizeScopes, "openid") {
return errors.New("authorize scope must include 'openid' so the callback gets an id_token")
}
if cfg.ClientID == "" {
return errors.New("proxy OIDC client ID must be configured")
} Prevention
- Always include the openid scope in the authorize request.
- Keep the ClientID exactly matching the ID token's aud claim.
- On key-rotation-prone IdPs, retry the full login flow once when verification fails mid-session.
- Watch for the precursor logs 'No id_token in OIDC response' / 'Failed to verify ID token' to classify the failure fast.
When it happens
Trigger: The IdP token response omits id_token (some setups only return an access token, or the authorization request lacked the 'openid' scope); the ID token's aud does not equal the configured ClientID; the token is signed with an algorithm or key the verifier rejects (keys rotated between discovery fetch and verify); the 'sub' claim is absent or claims decoding fails.
Common situations: The OIDC authorization request was built without scope 'openid', so no ID token is issued; ClientID typo means audience mismatch ('invalid audience'); IdP signing-key rotation mid-flow; a custom IdP that issues JWTs without a 'sub' claim; clock skew breaking exp/iat verification.
Related errors
- %s %s
- service domain is required
- identity provider name is required
- identity provider type is required
- unsupported identity provider type
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/1a76a2e1966081ef.
Report an issue: GitHub.