PKCE code_verifier mismatch on Genesys Cloud OAuth

Getting a 400 Bad Request with invalid_grant when swapping the authorization code for a token. The code_verifier in my POST body matches the S256 hash sent in the initial GET request, but the /oauth/token endpoint keeps rejecting it.

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=AUTH_CODE_HERE
&redirect_uri=http://localhost:3000/callback
&client_id=MY_CLIENT_ID
&code_verifier=PLAIN_TEXT_VERIFIER

The flow works fine without PKCE, so it’s definitely the verifier. Is there a specific encoding requirement for the Genesys endpoint?