Troubleshooting: OIDC/OAuth "Authorization Code Does Not Match or Has Already Been Used" Error

Follow
    Applies to:
  • SecureAuth Identity Platform
Deployment model:
  • Cloud
  • Hybrid
  • On Premises
  • Version Affected: All
     
     

    Overview

    When a service provider attempts to exchange an OIDC/OAuth Authorization Code for an access token, SecureAuth Identity Platform does not issue one. The Debug log shows an entry similar to:

    Message="[TokenEndpointHandler].[ValidateAuthorizationCodeFlow]: Authorization Code does not match or has already been used."

    This can have more than one root cause:

    • See Cause 1 - The Consent Storage attribute is not writable.
    • See Cause 2 - Active Directory replication lag in a multi-site deployment causes intermittent failures.

    The examples below assume the datastore is Active Directory, but the same causes apply to any other datastore type that has a similar replication flow.

     

    In this article


     

    Cause 1: Consent Storage Attribute Is Not Writable

    The attribute mapped to Consent Storage in the realm's Data tab has not been marked as writable by the Service Account. Identity Platform cannot write the authorization code to Active Directory, so the code is never stored and cannot be validated during the token exchange.

    This cause is likely when:

    • The error occurs on every authentication attempt, consistently.
    • The error is not affected by timing — slowing down the Authorization Code exchange makes no difference.

     

    Resolution 1:

    1. Open the Admin Console and go to the realm's Post Authentication and Data tab (Classic Experience) or Datastore - Properties (New Experience).
    2. Locate the attribute configured for Consent Storage.
    3. Confirm the Writable checkbox is ticked for that attribute.
    4. Confirm the Service Account used by the realm has write permission to that attribute in Active Directory.
    5. Save the changes and re-test.

    Classic Experience realms: newer versions of Identity Platform no longer have a Consent Storage Attribute field on the Post Authentication tab — that configuration is limited to the Data tab. On the Post Authentication tab of older versions, the field is named Consent Storage Attribute, for example set to Aux ID 1:

    The Post Authentication tab in the Classic Experience, showing Enable User Consent Storage set to True and the Consent Storage Attribute set to Aux ID 1.

    On the Data tab, the corresponding row may be labeled with the same Aux ID value used on the Post Authentication tab (for example, Aux ID 1 mapped to an attribute such as labeledURI), with the Writable checkbox checked on the right:

    A Data tab row for Aux ID 1, mapped to the attribute labeledURI as Plain Text, with the Writable checkbox checked.

    On versions where the Post Authentication tab has no Consent Storage Attribute field at all, the Data tab instead has its own dedicated row labeled Consent storage for OIDC:

    A Data tab row labeled Consent storage for OIDC, mapped to the attribute labeledURI as Plain Text, with the Writable checkbox checked.

    New Experience realms: the equivalent row is labeled OIDC Consent on the Datastore - Properties page, with its own Writable checkbox:

    The New Experience Datastore Properties page, showing an OIDC Consent row mapped to the attribute houseIdentifier as plain text, with its Writable checkbox checked.

     


     

    Cause 2: AD Replication Lag in a Multi-Site Deployment

    In environments with multiple Identity Platform nodes spread across more than one Active Directory site, a race condition can occur between the authorization code being written to Active Directory and the token exchange reading it back. When a user authenticates, Identity Platform writes the authorization code to the Consent Storage attribute on whichever Domain Controller it is connected to at that moment (for example, DC1 in Site A). The service provider then immediately sends the Authorization Code exchange request. If that request is routed to a different Domain Controller (for example, DC2 in Site B) before AD replication has propagated the entry from DC1 to DC2, Identity Platform finds no matching code and returns this error.

    This cause is likely when:

    • The error is intermittent — it does not occur on every attempt.
    • Consent Storage is enabled on the realm.
    • The Consent Storage attribute is confirmed writable (Cause 1 has been ruled out).
    • The error is more likely when the service provider processes quickly — slowing the flow down on the service provider's side can allow the Authorization Code exchange to succeed.
    • The environment spans more than one AD site, or Domain Controllers that are geographically distributed.

     

    Resolution 2:

    Option 1 — Pin the datastore to a single AD site (recommended): modify the OIDC realm's datastore connection string so that all Identity Platform nodes query Domain Controllers within the same AD site. Intra-site replication is close to instantaneous, which eliminates the race condition while keeping DC failover within that site.

    By default, SecureAuth performs an SRV lookup across every Domain Controller at the connection string's domain, with no site specified, so the realm can connect to any Domain Controller in the domain. To connect to a specific site instead:

    1. Open the SecureAuth Admin Console.
    2. Modify the realm's Datastore Connection String to include the site name. For example, if the connection string is currently LDAP://example.com/DC=example,DC=Com and you want to connect to Domain Controllers in a site named wood, change it to LDAP://wood._sites.example.com/DC=example,DC=Com.
    3. Save the change and test the connection. As long as there are multiple Domain Controllers in that site, DC failover is preserved.

    Option 2 — Pin the datastore to a single Domain Controller (not recommended for production): point the realm's datastore connection string directly at one Domain Controller. This eliminates replication lag entirely but removes all DC-level failover for that realm. It's suitable for confirming the root cause during troubleshooting, but not as a permanent fix.

    Option 3 — Disable Consent Storage (only where it isn't required): if the realm does not use the Introspection endpoint or Token Refresh, Consent Storage can be disabled on the realm's Post-Auth tab. Disabling Consent Storage will break the Introspect and Token Refresh endpoints for any application connected to this realm that uses them.

     

    SecureAuth Knowledge Base Articles provide information based on specific use cases and may not apply to all appliances or configurations. Be advised that these instructions could cause harm to the environment if not followed correctly or if they do not apply to the current use case.

    Customers are responsible for their own due diligence prior to utilizing this information and agree that SecureAuth is not liable for any issues caused by misconfiguration directly or indirectly related to SecureAuth products.

    0 out of 0 found this helpful

    Comments

    0 comments

    Please sign in to leave a comment.