apache/pulsar · error · IllegalArgumentException

Unsupported media type or encoding format: ${contentType}

Error message

Unsupported media type or encoding format: ${contentType}

What it means

DefaultCryptoKeyReader.loadKey() reads encryption keys via URL. For data: URIs the content must be a PEM-encoded key (application/x-pem-file); any other media type or encoding is rejected with IllegalArgumentException so a wrong-format key is never silently used for encryption.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/DefaultCryptoKeyReader.java:96

            log.warn().attr("keyName", keyName).log("Private key is not set");
        } else {
            try {
                keyInfo.setKey(loadKey(privateKey));
            } catch (Exception e) {
                log.error().attr("keyName", keyName).exception(e).log("Failed to load private key");
            }
        }

        return keyInfo;
    }

    private byte[] loadKey(String keyUrl) throws IOException, IllegalAccessException, InstantiationException {
        try {
            URLConnection urlConnection = new URL(keyUrl).openConnection();
            try {
                String protocol = urlConnection.getURL().getProtocol();
                if ("data".equals(protocol) && !APPLICATION_X_PEM_FILE.equals(urlConnection.getContentType())) {
                    throw new IllegalArgumentException(
                            "Unsupported media type or encoding format: " + urlConnection.getContentType());
                }
                return IOUtils.toByteArray(urlConnection);
            } finally {
                IOUtils.close(urlConnection);
            }
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException("Invalid key format");
        }
    }

}

View on GitHub (pinned to 820761864e)

Solutions

  1. Use data:application/x-pem-file;base64,<base64-encoded-PEM> as the key URL.
  2. Convert the key to PEM format (e.g. openssl rsa -inform DER -outform PEM) and re-encode.
  3. Serve keys over file: or http(s): URLs instead of data: URIs.

Example fix

// before
String keyUrl = "data:application/octet-stream;base64," + b64(pemBytes);
// after
String keyUrl = "data:application/x-pem-file;base64," + b64(pemBytes);
Defensive patterns

Strategy: validation

Validate before calling

String url = keyUrl;
if (url.startsWith("data:")) {
  String meta = url.substring(5, url.indexOf(','));
  if (!meta.contains("application/x-pem-file")) {
    throw new IllegalArgumentException("data URI must be application/x-pem-file");
  }
}

Try / catch

try {
  reader.getPublicKey(keyName);
} catch (IllegalArgumentException e) {
  // unsupported media type: fix data URI MIME type to application/x-pem-file
}

Prevention

When it happens

Trigger: Passing a key URL with a data: scheme whose content type is not application/x-pem-file — e.g. data:application/octet-stream;base64,... or a missing/wrong MIME parameter — via ReaderConfig keyReader with getPublicKey/getPrivateKey resolving that URL.

Common situations: Hand-built data: URIs missing the ;base64 parameter or using the wrong MIME type; keys generated by tools that emit DER instead of PEM; misconfigured key URLs in producer encryption configs.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/8417b9ccf98ee9cf. Report an issue: GitHub.