apache/beam · error · IOException

Azure credentials provider type name key '%s' not found

Error message

Azure credentials provider type name key '%s' not found

What it means

deserializeWithType looks up the type-discriminator property (from typeDeserializer.getPropertyName()) in the parsed map to decide which TokenCredential subclass to rebuild. If that key is absent, it throws IOException "Azure credentials provider type name key '%s' not found" — the serialized payload lacks the @class/type marker the module needs.

Source

Thrown at sdks/java/io/azure/src/main/java/org/apache/beam/sdk/io/azure/options/AzureModule.java:106

    public TokenCredential deserialize(JsonParser jsonParser, DeserializationContext context)
        throws IOException {
      return context.readValue(jsonParser, TokenCredential.class);
    }

    @Override
    public TokenCredential deserializeWithType(
        JsonParser jsonParser, DeserializationContext context, TypeDeserializer typeDeserializer)
        throws IOException {
      Map<String, String> asMap =
          jsonParser.readValueAs(new TypeReference<Map<String, String>>() {});
      if (asMap == null) {
        throw new IOException("Azure credentials provider could not be read.");
      }

      String typeNameKey = typeDeserializer.getPropertyName();
      String typeName = asMap.get(typeNameKey);
      if (typeName == null) {
        throw new IOException(
            String.format("Azure credentials provider type name key '%s' not found", typeNameKey));
      }

      if (typeName.equals(DefaultAzureCredential.class.getSimpleName())) {
        return new DefaultAzureCredentialBuilder().build();
      } else if (typeName.equals(ClientSecretCredential.class.getSimpleName())) {
        return new ClientSecretCredentialBuilder()
            .clientId(asMap.getOrDefault(AZURE_CLIENT_ID, ""))
            .clientSecret(asMap.getOrDefault(AZURE_CLIENT_SECRET, ""))
            .tenantId(asMap.getOrDefault(AZURE_TENANT_ID, ""))
            .build();
      } else if (typeName.equals(ManagedIdentityCredential.class.getSimpleName())) {
        return new ManagedIdentityCredentialBuilder()
            .clientId(asMap.getOrDefault(AZURE_CLIENT_ID, ""))
            .build();
      } else if (typeName.equals(EnvironmentCredential.class.getSimpleName())) {
        return new EnvironmentCredentialBuilder().build();
      } else if (typeName.equals(ClientCertificateCredential.class.getSimpleName())) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Serialize credentials only through AzureModule so the type-discriminator field is written; do not hand-craft the JSON.
  2. Add the expected type-name property (e.g. "@class": "DefaultAzureCredential") to the payload.
  3. Confirm the same AzureModule/type-deserializer configuration is used on both write and read sides.
  4. If migrating, re-serialize the credential from a live TokenCredential object instead of patching old JSON.

Example fix

// before
{"clientId":"...","tenantId":"..."} // missing type key
// after
{"@class":"ClientSecretCredential","clientId":"...","tenantId":"..."}
Defensive patterns

Strategy: validation

Validate before calling

if (!payload.containsKey("@class")) { // or the configured type property name
  throw new IllegalArgumentException("credential JSON missing type discriminator");
}

Try / catch

try {
  return deserialize(json);
} catch (IOException e) {
  if (e.getMessage().contains("type name key")) {
    LOG.error("credential payload lacks the type discriminator; re-serialize via AzureModule");
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a credential JSON object that omits the type-name property (e.g. hand-crafted JSON, or a payload written by a serializer without the type suffix); key-name mismatch between serializer versions.

Common situations: Manually constructing credential JSON in pipeline templates; payloads from a different Jackson setup (no default typing) that dropped the discriminator; editing serialized options and accidentally deleting the type field.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/a78a3bc37c240b93. Report an issue: GitHub.