apache/beam · error · IOException

Failed to serialize object of type

Error message

Failed to serialize object of type '%s': %s

What it means

serializeWithType reads private fields (identityClient, clientId, etc.) from credential objects via reflection; if that access fails with IllegalAccessException or NoSuchFieldException, it wraps the cause into IOException "Failed to serialize object of type '%s': %s". This happens when the Azure SDK identity library's internal field layout changed.

Solutions

  1. Pin azure-identity to the version the Beam io-azure module was built against (check beam sdks/java/io/azure build files).
  2. Upgrade the Beam Azure IO module to a release compatible with your azure-identity version.
  3. Avoid pulling a newer azure-identity transitively; align dependencyManagement/force versions.
  4. Use DefaultAzureCredential, whose serialization path avoids deep reflection on these fields.

Example fix

// before (build.gradle)
implementation 'com.azure:azure-identity:1.15.0' // field layout changed
// after
implementation('com.azure:azure-identity') {
  version { strictly('1.11.4') } // matches Beam AzureModule expectations
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify expected internal field exists before serializing
Field f = credential.getClass().getDeclaredField("identityClient"); // NoSuchFieldException => version mismatch

Try / catch

try {
  mapper.writeValue(out, options);
} catch (IOException e) {
  if (e.getMessage().startsWith("Failed to serialize object of type")) {
    LOG.error("azure-identity version mismatch with Beam AzureModule reflection; pin azure-identity");
  }
  throw e;
}

Prevention

When it happens

Trigger: Serializing ClientSecretCredential/UsernamePasswordCredential/AppService MSI credentials against an azure-identity version where the reflected fields ('identityClient', 'clientId', 'username', 'password') were renamed, removed, or made inaccessible (module/JPMS restrictions).

Common situations: Upgrading azure-identity in the dependency tree so Beam's AzureModule reflection breaks; running under Java module system strict access; mismatched Beam and azure-identity versions.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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

Appendix: source

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

        } else if (tokenCredential instanceof ClientCertificateCredential) {
          throw new IOException("Client certificates not yet implemented"); // TODO
        } else if (tokenCredential instanceof UsernamePasswordCredential) {
          UsernamePasswordCredential credential = (UsernamePasswordCredential) tokenCredential;
          IdentityClient identityClient = (IdentityClient) getMember(credential, "identityClient");
          jsonGenerator.writeStringField(
              AZURE_CLIENT_ID, (String) getMember(identityClient, "clientId"));
          jsonGenerator.writeStringField(
              AZURE_USERNAME, (String) getMember(credential, "username"));
          jsonGenerator.writeStringField(
              AZURE_PASSWORD, (String) getMember(credential, "password"));
        } else {
          throw new IOException(
              String.format(
                  "Azure credential provider type '%s' is not supported",
                  tokenCredential.getClass().getSimpleName()));
        }
      } catch (IllegalAccessException | NoSuchFieldException e) {
        throw new IOException(
            String.format(
                "Failed to serialize object of type '%s': %s",
                tokenCredential.getClass().getSimpleName(), e.toString()));
      }

      typeSerializer.writeTypeSuffix(jsonGenerator, typeIdDef);
    }
  }
}

View on GitHub (pinned to 12126d8942)