Keycloak Fails (500 Internal Server Error) – But `curl` Works

Hi everyone,

I’m trying to set up FreeRADIUS (v3.2.7) to authenticate users via Keycloak using the REST module and the OpenID Connect token endpoint. However, although authentication works fine when I use curl, it fails with a 500 Internal Server Error when FreeRADIUS makes the request.


Server1 : FreeRADIUS (v3.2.7)

Server2 : Keycloak (v26.1.4)

OS : Rocky Linux release 8.10 (Green Obsidian)


:white_check_mark: curl Works

curl -k -X POST https://<keycloak-host>:8443/realms/myrealm/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&client_id=<client-id>&client_secret=<client-secret>&username=testkim&password=1q2w3e4r"

This returns a valid access_token, so I know Keycloak is configured correctly.


:cross_mark: FreeRADIUS Fails

But when FreeRADIUS sends the same request, I get this error:

HTTP Request to /realms/myrealm/protocol/openid-connect/token failed
java.lang.IllegalArgumentException: Failed to parse media type form

In the FreeRADIUS debug logs:

(0) rest: Sending HTTP POST to "https://<keycloak-host>:8443/realms/myrealm/protocol/openid-connect/token"
(0) rest: Status : 500 (Internal Server Error)
(0) rest: ERROR: Server returned:
(0) rest: ERROR: {"details":"Error id <some-id>","stack":""}

:wrench: My mods-enabled/rest Config

rest {
    connect_timeout = 4.0

    authenticate {
        uri = "https://<keycloak-host>:8443/realms/myrealm/protocol/openid-connect/token"
        method = "post"
        body = "form"
        data = "grant_type=password&client_id=<client-id>&client_secret=<client-secret>&username=%{request:User-Name}&password=%{request:User-Password}"
        header = "Content-Type: application/x-www-form-urlencoded"

        status_check_success = yes

        tls {
            ca_file = "/usr/local/etc/raddb/certs/keycloak.crt"
            check_cert = no
            check_cert_cn = no
        }
    }
}

What I Tried

  • Removed connect_uri and used full uri
  • Verified headers and body match the curl request
  • curl from the same server works fine
  • TLS/cert verification is disabled for now

My Guess

I suspect FreeRADIUS isn’t setting the Content-Type correctly — or something subtle in the REST call is different from curl.


Question

Has anyone else encountered this? How can I debug what FreeRADIUS is really sending, or fix this media type error?

Thanks in advance!