Skip to content

Refresh token reuse after rotation may cause intermittent invalid_grant with external OIDC provider #866

@croessner

Description

@croessner

Title

[BUG] Desktop client sometimes fails refresh_token exchange with invalid_grant against external OIDC provider

Steps to reproduce

  1. Configure the OpenCloud Desktop client against an OpenCloud server that uses an external OIDC provider.
  2. In this setup, the external IdP is Nauthilus.
  3. Log in successfully with the desktop client.
  4. Let the client run for a longer period so token refresh happens in the background.
  5. Eventually the desktop client hits a failed refresh request with grant_type=refresh_token.

Expected behavior

The desktop client should silently refresh tokens in the background and continue to use the newest refresh token without requiring re-authentication.

Actual behavior

After working fine for hours, the desktop client suddenly fails with an authorization error. On the IdP side, the failing request is a token endpoint request with:

  • grant_type=refresh_token
  • HTTP status 400
  • response body {"error":"invalid_grant"}

From the user perspective this shows up as an "Access denied" style failure even though the session was previously working.

Why this issue may be different from existing desktop issues

This does not look like the same problem as:

This issue is specifically about a refresh token exchange that worked for a long time and then suddenly starts failing with invalid_grant.

Important note

On the IdP side, the token endpoint behavior appears correct.

The Nauthilus logs show that the failing requests are grant_type=refresh_token requests returning 400, and the server-side analysis indicates that the rejected token was already invalid, expired, or already rotated.

That means the interesting question is whether the desktop client may sometimes keep or reuse an outdated refresh token instead of the newest rotated one.

Questions

  • Is there any known race or persistence issue in the desktop client's token storage?
  • Could the desktop client under some circumstances retry with an already rotated refresh token?
  • Are there code paths where the newest refresh token returned by the IdP is not reliably stored?

Environment

  • Client: OpenCloud Desktop
  • External IdP: Nauthilus
  • OIDC flow includes offline_access

Additional context

I am seeing similar refresh-token-related failures on iOS as well, but this issue is specifically about the desktop client.

If useful, I can provide:

  • desktop client logs with HTTP logging enabled
  • matching Nauthilus token endpoint logs with request timestamps
  • examples of successful refreshes followed later by invalid_grant

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions