quarkusio/quarkus · error · IllegalArgumentException
Unsupported media type or encoding format: ${contentType}
Error message
Unsupported media type or encoding format: ${contentType} What it means
A Graal substitution replacing Pulsar's KeyFileLoader private-key loading for native compatibility. When the key URL uses the 'data:' protocol, the substitution only accepts application/json content type and throws IllegalArgumentException for any other media type, since data URIs must carry the JSON key file.
Source
Thrown at extensions/smallrye-reactive-messaging-pulsar/runtime/src/main/java/io/quarkus/pulsar/runtime/graal/Substitutions.java:39
final class Target_com_scurrilous_circe_checksum_Crc32cIntChecksum {
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias)
@Alias
private static IntHash CRC32C_HASH = new Java8IntHash();
}
@TargetClass(className = "org.apache.pulsar.client.impl.auth.oauth2.ClientCredentialsFlow")
final class Target_org_apache_pulsaR_client_impl_auth_oauth2_ClientCredentialsFlow {
@Substitute
private static KeyFile loadPrivateKey(String privateKeyURL) throws IOException {
try {
URLConnection urlConnection = new org.apache.pulsar.client.api.url.URL(privateKeyURL).openConnection();
try {
String protocol = urlConnection.getURL().getProtocol();
if ("data".equals(protocol) && !"application/json".equals(urlConnection.getContentType())) {
throw new IllegalArgumentException(
"Unsupported media type or encoding format: " + urlConnection.getContentType());
}
KeyFile privateKey;
try (Reader r = new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8)) {
privateKey = KeyFile.fromJson(r);
}
return privateKey;
} finally {
IOUtils.close(urlConnection);
}
} catch (URISyntaxException | InstantiationException | IllegalAccessException e) {
throw new IOException("Invalid privateKey format", e);
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Use data:application/json;base64,<base64-encoded JSON key file> for the key URI
- Store the key in a file and reference it via file: URL instead of a data URI
- Verify the data URI media type matches application/json exactly
Example fix
// before String key = "data:text/plain;base64," + Base64.getEncoder().encodeToString(jsonKeyBytes); // after String key = "data:application/json;base64," + Base64.getEncoder().encodeToString(jsonKeyBytes);
Defensive patterns
Strategy: validation
Validate before calling
static String toValidKeyDataUri(Path jsonKeyFile) throws IOException {
byte[] bytes = Files.readAllBytes(jsonKeyFile);
return "data:application/json;base64," + Base64.getEncoder().encodeToString(bytes);
}
// call before configuring the client: ensure the file parses as JSON
new String(bytes, StandardCharsets.UTF_8).trim().startsWith("{"); Type guard
static boolean isValidJsonDataUri(String uri) {
return uri != null && uri.startsWith("data:application/json");
} Try / catch
try {
client = PulsarClient.builder().serviceUrl(url)
.auth(AuthenticationFactory.token(...))
.authentication(AuthenticationTLS).build();
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported media type")) {
throw new ConfigurationException("Key data: URI must use media type application/json", e);
}
throw e;
} Prevention
- Always encode Pulsar key files as data:application/json;base64,...
- Prefer file: URLs over data: URIs for key material
- Validate the key file is Pulsar JSON format (not PEM) before configuring auth
When it happens
Trigger: Configuring a Pulsar client token/key pair with a data: URI whose media type is not application/json (e.g. data:text/plain;base64,...) for authPrivateKey/authPublicKey in native mode.
Common situations: Embedding base64 private keys in config using data:text/plain or data:application/x-pem-file URIs; hand-built data URIs missing the application/json type.
Related errors
- Invalid privateKey format
- No configuration is available
- The fixed port must be greater than 0
- io_uring is not supported with Netty 4.2
- service interface name cannot be null or blank
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/181056cbd358f708.
Report an issue: GitHub.