Recurring 302 Redirect due to "session not associated with identity provider"

What happened?

I have a fairly basic self-hosted authentication configuration (single-node at the moment) using oidc for the provider but after successful authentication I’m receiving another 302 back to the IDP provider login with a logged message indicating my session isn’t associated with identity provider:

{"level":"info","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36","request-id":"7eed4db2-0fb0-453e-84ba-a428435c9f0c","idp-id":"ejFCB5inZIuwjfgfGPtbEZ2fJfNxCSC19WCamkfUPeII","session-idp-id":"hg_3KcaIXQYzRnpnkK8holyHAfYYuE04cDUibZzkODw","id":"dE4szqsiifmNEwDAECtTMd90R-0oSx1rg-U4nFmYdtk","time":"2025-09-05T18:24:13Z","message":"authenticate: session not associated with identity provider"}

My IDP client is configured with redirect_uri (included base URI without the subpath as well)https://auth.sub.example.com/oauth2/callback. I’ve tried this with my data broker as in-memory and with Postgres, all with the same results. This same config works great if using google as the target provider (using in-memory or Postgres hosted databroker service). This feels like something simple I’m overlooking.

curl -vkI https://ec21cf15.wild.sub.example.com 2>&1  | tr -d '\r'  | sed -n 's/^< location: .*pomerium_idp_id=\([^&]*\).*/\1/p'

ejFCB5inZIuwjfgfGPtbEZ2fJfNxCSC19WCamkfUPeII

What did you expect to happen?

Successful redirect to the application managed by my Pomerium route since the authentication succeeds

How’d it happen?

  1. Ran pomerium version 0.30.5 with self-hosted authentication service and upstream oidc provider configured.
  2. Accessed route https://ec21cf15.wild.sub.example.com
  3. Redirected to IDP login (successful 302)
  4. Authenticated with IDP (no errors)
  5. Redirected back to IDP login (302)
  6. session not associated with identity provider logged by Pomerium

What’s your environment like?

  • Pomerium version (retrieve with pomerium --version):
    pomerium version pomerium: 0.30.5+7caf5a7d0
    envoy: 1.34.1-p1+9ec36081054ab217ff261a4696693013a3e85eb98c72448cd9b49878fb810332
  • Server Operating System/Architecture/Cloud:
    • Runnining on GCP with:
    • Distributor ID: Ubuntu
      Description:    Ubuntu 22.04.5 LTS
      Release:        22.04
      Codename:       jammy
      

What’s your config.yaml?

address: :443

certificates:
  - cert: /etc/certs/fullchain.pem
    key: /etc/certs/privkey.pem

cookie_secret: mycookiesecret
cookie_name: _pomerium_example
cookie_secure: true
routes:

- from: https://ec21cf15.wild.sub.example.com
  to: http://10.0.0.2:2003
  tls_skip_verify: true
  allow_websockets: true
  preserve_host_header: true
  pass_identity_headers: true
  timeout: 0s
  idle_timeout: 0s
  policy:
    allow:
      or:
      - email:
          is: me@example.com
          
log_level: info
log_format: json
metrics_address: :9090
timeout_read: 0s
timeout_write: 0s
timeout_idle: 0s
cors_allow_preflight: true
cors_allowed_origins:
- '*'
cors_allowed_methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
cors_allowed_headers:
- '*'
pass_identity_headers: true
authenticate_service_url: https://auth.sub.example.com

idp_provider: oidc
idp_provider_url: https://login.example.com
idp_client_id: "myclientid"
idp_client_secret: "myclientsecret"
jwt_claims_headers:
- email
- name
- sub

What did you see in the logs?

{"level":"info","ip":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36","request-id":"7eed4db2-0fb0-453e-84ba-a428435c9f0c","idp-id":"ejFCB5inZIuwjfgfGPtbEZ2fJfNxCSC19WCamkfUPeII","session-idp-id":"hg_3KcaIXQYzRnpnkK8holyHAfYYuE04cDUibZzkODw","id":"dE4szqsiifmNEwDAECtTMd90R-0oSx1rg-U4nFmYdtk","time":"2025-09-05T18:24:13Z","message":"authenticate: session not associated with identity provider"}

Additional context

N/A

Hi there,

Thanks for using Pomerium! Let’s see if we can get to the bottom of this.

Few questions to help understand the situation:

Thanks!

Thank you for the reply, and a very cool product :slight_smile:

  • Which identity provider are you using?

    • This is our corporate OIDC provider/broker. I can’t provide too many details, but I can confirm I was able to get this working as expected with Dex as an intermediary with Pomerium still providing authorization & proxy functions (see details below). It’s a standard OIDC provider and we’ve historically used oauth2-proxy without issue but needed more granular access policies (which is why Pomerium is a great fit!)
  • Does the idp_provider_url value match the issuer value in https://login.example.com/.well-known/openid-configuration?

    • Yes - this matches 1:1
    • {
        "issuer": "https://login.example.com",
        "authorization_endpoint": "https://login.example.com/authorize",
        "token_endpoint": "https://login.example.com/token",
        "userinfo_endpoint": "https://login.example.com/userinfo",
        "end_session_endpoint": "https://login.example.com/logout",
        "jwks_uri": "https://login.example.com/.well-known/jwks.json",
        "scopes_supported": [
          "openid",
          "consent",
          "consent_u",
          "email",
          "profile",
          "phone",
          "address",
          "geoip",
          "authz",
          "roles",
          "member_of",
          "birthdate",
          "age",
          "usr_admin",
          "usr_block",
          "grp_admin"
        ],
        "response_types_supported": [
          "code",
          "id_token",
          "id_token token",
          "code id_token",
          "code token",
          "code id_token token"
        ],
        "response_modes_supported": [
          "query",
          "fragment"
        ],
        "subject_types_supported": [
          "public"
        ],
        "id_token_signing_alg_values_supported": [
          "ES256",
          "RS256"
        ],
        "token_endpoint_auth_methods_supported": [
          "client_secret_basic",
          "client_secret_post"
        ]
      }
      
  • Have you switched from google auth recently? Maybe change the cookie_name temporarily to ensure no collision with older sessions.

    • I did modify the cookie_name value multiple times, and also cleared out & dropped the Postgres DB (and any temp/cache dir when switching from DB to memory-backed databroker), but the same issue persisted.

Here’s the current workaround using OIDC IdP > Dex (custom port) > Pomerium

# Pomerium conf identical to original shared configuration with this change to provider:
idp_provider_url: https://auth-dex.sub.example.com:8443
idp_client_id: pomerium
idp_client_secret: pomerium_client_secret

Pretty simple Dex conf:

issuer: https://auth-dex.sub.example.com:8443
storage:
  type: sqlite3
  config:
    file: /config/dex.db

oauth2:
  skipApprovalScreen: true
  responseTypes: ["code", "id_token", "token"]

web:
  https: 0.0.0.0:5558 # mapped to 8443 via docker
  tlsCert: /config/tun-fullchain.pem
  tlsKey: /config/tun-privkey.pem


# Sets Pomerium as our client now
staticClients:
- id: pomerium
  name: Pomerium
  secret: pomerium_client_secret 
  redirectURIs:
  - https://auth.sub.example.com/oauth2/callback # Pomerium callback

# Matches previos idp_ configuration values from Pomerium
connectors:
- type: oidc
  id: myclientid
  name: Example Login
  config:
    issuer: https://login.example.com
    clientID: myclientid
    clientSecret: myclientsecret
    redirectURI: https://auth-dex.sub.example.com:8443/callback
    scopes:
    - openid
    - profile
    - email
    getUserInfo: true           # fetch missing claims via UserInfo
    userIDKey: sub              # defaults to sub; explicit for clarity
    userNameKey: email

This actually works great, but I do hate the idea of having multiple OIDC layers in the mix… and honestly, I validated my idp-id is correct per our federated auth team. We’re at a loss as to where session-idp-id is coming from or being generated. I can’t replicate this with oauth2-proxy or Dex either… Thank you again for any insights you could provide!

Hi @liveaverage ,

Pomerium supports multiple identity provider configurations, for example you can specify a different client id and client secret for a route. The way this works is that we pass a hash of the settings to and from the identity provider, and use that to know which configuration to use. This error:

authenticate: session not associated with identity provider

indicates that the current session is associated with a different hash of the identity provider settings than the one coming back from the identity provider.

The login process involves multiple redirects:

  1. example.com
  2. authenticate.example.com/.pomerium/sign_in
  3. idp
  4. authenticate.example.com/oauth2/callback
  5. example.com

Steps (2) and (4) should have a pomerium_idp_id query string parameter. Do you see that? Do they match?

A mismatch could happen if multiple instances of Pomerium are re-using the same session with different IdP settings, or if the settings were constantly changing, or if during redirect somehow those parameters are being lost?