K
Kinde2mo ago
_.Mass._

listing users via api returns the wrong identity

Hi, when listing users via /api/v1/users?user_id=<kp:123> we get a different identity back kp:456. This is a major issue that's impacting the functionality of our product. Can someone please look into it? Here is the curl:
❯ curl --location 'https://ankor-dev.au.kinde.com/api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1' \
--header 'Authorization: Bearer ***' -v
* Host ankor-dev.au.kinde.com:443 was resolved.
* IPv6: (none)
* IPv4: 54.153.128.229, 13.54.219.39
* Trying 54.153.128.229:443...
* Connected to ankor-dev.au.kinde.com (54.153.128.229) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=*.kinde.com
* start date: Apr 8 00:00:00 2025 GMT
* expire date: May 8 23:59:59 2026 GMT
* subjectAltName: host "ankor-dev.au.kinde.com" matched cert's "*.au.kinde.com"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
* SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://ankor-dev.au.kinde.com/api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: ankor-dev.au.kinde.com]
* [HTTP/2] [1] [:path: /api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [authorization: Bearer ***
> GET /api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1 HTTP/2
> Host: ankor-dev.au.kinde.com
> User-Agent: curl/8.7.1
> Accept: */*
> Authorization: Bearer ***
>
* Request completely sent off
< HTTP/2 200
< date: Wed, 08 Oct 2025 22:13:55 GMT
< content-type: application/json; charset=utf-8
< content-length: 338
< vary: Accept-Encoding
<
* Connection #0 to host ankor-dev.au.kinde.com left intact
{"code": "OK", "users": [{"id": "kp:58930e2164f548c4bc259993d1d300eb", "email": "***", "full_name": "***", "last_name": "***", "created_on": "2024-04-10T07:57:55.035431+00:00", "first_name": "***", "is_suspended": false, "total_sign_ins": 0, "failed_sign_ins": 0}], "message": "Success", "next_token": "***"}%
❯ curl --location 'https://ankor-dev.au.kinde.com/api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1' \
--header 'Authorization: Bearer ***' -v
* Host ankor-dev.au.kinde.com:443 was resolved.
* IPv6: (none)
* IPv4: 54.153.128.229, 13.54.219.39
* Trying 54.153.128.229:443...
* Connected to ankor-dev.au.kinde.com (54.153.128.229) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=*.kinde.com
* start date: Apr 8 00:00:00 2025 GMT
* expire date: May 8 23:59:59 2026 GMT
* subjectAltName: host "ankor-dev.au.kinde.com" matched cert's "*.au.kinde.com"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
* SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://ankor-dev.au.kinde.com/api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: ankor-dev.au.kinde.com]
* [HTTP/2] [1] [:path: /api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [authorization: Bearer ***
> GET /api/v1/users?user_id=kp%3A472264654f30408f8e84c2b0f7347edd&page_size=1 HTTP/2
> Host: ankor-dev.au.kinde.com
> User-Agent: curl/8.7.1
> Accept: */*
> Authorization: Bearer ***
>
* Request completely sent off
< HTTP/2 200
< date: Wed, 08 Oct 2025 22:13:55 GMT
< content-type: application/json; charset=utf-8
< content-length: 338
< vary: Accept-Encoding
<
* Connection #0 to host ankor-dev.au.kinde.com left intact
{"code": "OK", "users": [{"id": "kp:58930e2164f548c4bc259993d1d300eb", "email": "***", "full_name": "***", "last_name": "***", "created_on": "2024-04-10T07:57:55.035431+00:00", "first_name": "***", "is_suspended": false, "total_sign_ins": 0, "failed_sign_ins": 0}], "message": "Success", "next_token": "***"}%
We are basically requesting kp:472264654f30408f8e84c2b0f7347edd and getting back kp:58930e2164f548c4bc259993d1d300eb. Like I said this is a major issue in our product. We are temporarily disabling access to that account however we do not know how many accounts are affected.
14 Replies
Krish - Kinde
Krish - Kinde2mo ago
Hi, Thank you for reaching out. I'll check with the team and get back to you.
Krish - Kinde
Krish - Kinde2mo ago
Hi, It looks like the issue is happening because the user with ID kp:472264654f30408f8e84c2b0f7347edd doesn’t exist in that environment. The endpoint being used (/api/v1/users) is designed to list users, not fetch a specific one. Since the request includes page_size=1, it’s returning the next available user in the list rather than the one you’re trying to retrieve. If your goal is to fetch a specific user by ID, please use the single-user endpoint instead: GET /api/v1/user?user_id=kp:472 (Ref here: https://docs.kinde.com/kinde-apis/management/#tag/users/get/api/v1/user) The dev team also noted that ideally, if a user_id is passed to the /users endpoint and not found, it should return null rather than the next user in the list. We’ve passed this feedback on for consideration in a future update.
Kinde docs
Kinde Management API
The management API is for managing your Kinde account. Most things that can be done via the Kinde admin UI can be done with this API
_.Mass._
_.Mass._OP2mo ago
Hi, thank you for your reply. There are a few things to unpack there, I'll try to be concise. 1. If a listing api provides filtering and none of the records match the filter, common logic is the returned array should be empty. It seems kinda arbitrary that the one identity is returned. Why 1 and not 10 or 20 (fair I pass the page_size, that explains it edited)? Also the endpoint is giving me something I haven't really requested. 2. We extract the kp id from the jwt token which means that at some point someone logged in with a token that had that kp id. If a user logged in with a token that had a kp id that doesn't exist in our environment then it's a major security concern. Where did that id came from? My goal is to return a list of user identities, we have a caching layer so say we are listing 10 and 9 are cached we would call kinde to only list the one missing identity. We are dealing with arrays so it seems very impractical to use a different endpoint if the list size is 1. Is there any update on this one? I am particularly interested about figuring out 2., how is it possible that a jwt on our dev env contains a kp id that does not exist in any of our environments?
Koosha-Kinde
Koosha-Kinde2mo ago
Hi Mass, Thanks a lot for the detailed follow-up. This is really helpful context. 1. You’re absolutely right about the expected behavior. If a filter returns no matches, the result should be an empty array rather than another record. The dev team has already raised a PR to correct this, so the /users endpoint will soon handle unmatched filters safely and predictably. Thank you for catching this and bringing it to our attention. 2. About the kp: ID not existing in your environment, one likely explanation is that the token was issued from a different Kinde environment, such as staging or production. You can confirm this by decoding the JWT and checking the iss claim, which should match your dev environment’s URL. It could also be a case where the user was deleted or removed since the token was issued, which would lead to the same result. If the token’s issuer matches your dev environment and the user has not been deleted, please let us know and we’ll dig deeper with the engineering team. Thanks again for raising this so clearly and for your patience while we get this fixed.
_.Mass._
_.Mass._OP2mo ago
Hi Roshan, thank you for your update. Since the team has raised a PR we won't be making any changes to how we consume the api. So far we have found this issue in our dev env only. As per the kp id, I could not find it in any of our environments. It's highly unlikely someone on our end manually deleted the user but I can't confirm it with absolute confidence at this stage. I'll check internally with the other teams but like I said this is highly unlikely. As per the token issued from a different kinde env, if that was the case we would still find the kp id in at least one of our env. Additionally the jwks used for validation are different so the call would not get past our authentication middleware. Could this be an issue caused by the september incident "user authenticated to wrong account"? We store the kp id in our iam federated table when a user signs-up and I wonder if a user signed up during the incident and was logged in with a wrong identity. I guess that could explain how we ended up with a kp id that doesn't exist in our envs, but that's just a speculative hypothesis on my end.
Krish - Kinde
Krish - Kinde2mo ago
Hi, Team deployed a fix so that no user records are returned if the API request contains a key that does not exist.Could you please confirm this and let us know.
_.Mass._
_.Mass._OP2mo ago
Hi Krish, the Roshan bot agreed with the empty array solution but I can see the response returns null. I am confused what is the expected behaviour if I pass 2 ids and 1 is found do I get an array with 2 elements where 1 is null? the issue would be fixed for us if we get an empty array. If you can explain how the endpoint behaves I can change the implementation accordingly. Also, maybe don' have your Roshan Bot agreeing with my solution when in the end you implement a different solution
Krish - Kinde
Krish - Kinde2mo ago
Hi, There seems to have been a bit of miscommunication. We’ll check with the team regarding the fix and update you soon as possible. Just to clarify, Roshan is not a bot, he’s part of our support team.
_.Mass._
_.Mass._OP2mo ago
lol I apologise, I assumed it was because of the "You are absolutely right" and the app label next to it. Thank you both for your help, waiting for your confirmation on the behaviour so we can adjust how we consume the api if required.
Krish - Kinde
Krish - Kinde2mo ago
The fix for this issue (returning an empty array instead of null) is expected to be deployed tomorrow. Apologies for the delay, and thank you for your patience.
_.Mass._
_.Mass._OP2mo ago
all good no worries, thank you for the update
Krish - Kinde
Krish - Kinde2mo ago
Could you please check now
_.Mass._
_.Mass._OP2mo ago
Hi Krish, confirming everything is working as expected using the query param for empty array. Thank you.
Krish - Kinde
Krish - Kinde2mo ago
That's great! Thank you for the confirmation.

Did you find this page helpful?