Why does the OIDC /authorize endpoint return a redirect_uri with query params after a hashtag/pound sign instead of a question mark?

In Okta’s OIDC /authorize endpoint (OpenID Connect & OAuth 2.0 API | Okta Developer), when using a code auth flow, it appends #code=1234-5678-9012 to the end of the redirect_uri instead of appending the same url param with a question mark ("?"). The docs don’t specifically say that they are appended as a query string / URL param, but that would seem to make things easier for developers like me who are used to parsing a URL for individual params. This isn’t possible with the hashtag ("#"), and I have to manually regex for the code value.

I’m not necessarily asking for a change but more trying to understand why it was built this way. Thanks!

Definition of a query string / URL params: Query string - Wikipedia

Check out the information in our documentation about response_mode, as that should provide the insight you need about why the code is being returned as hash fragment instead of as a query parameter: OpenID Connect & OAuth 2.0 API | Okta Developer

If id_token or token is specified as the response type, then query isn’t allowed as a response mode. Defaults to fragment in implicit and hybrid flows.

If you want it to be a fragment instead and you’re using an eligible flow, just include response_mode=fragment in your /authorize parameters

Okay thanks, so fragment means after a hash. I was using fragment because of that requirement for token response types, but didn’t know the implications.

Though, the docs only explain in what situations it would be a hash fragment, but not why. Is there a security difference between returning the code value in a hash fragment instead of query param?