apache/pulsar · error · PulsarAdminException

Unexpected monitoring class: ${monClass}

Error message

Unexpected monitoring class: ${monClass}

What it means

ResourceGroup.checkMonitoringClass only accepts Publish or Dispatch monitoring classes; any other ResourceGroupMonitoringClass value reaches the limit/usage accounting path and throws PulsarAdminException. This guards internal resource-group stats code from unhandled enum extensions.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/resourcegroup/ResourceGroup.java:435

    // Visibility for unit testing
    protected static long getRgUsageReportedCount (String rgName, String monClassName) {
        return (long) rgLocalUsageReportCount.labels(rgName, monClassName).get();
    }

    // Visibility for unit testing
    protected static BytesAndMessagesCount accumulateBMCount(BytesAndMessagesCount ... bmCounts) {
        BytesAndMessagesCount retBMCount = new BytesAndMessagesCount();
        for (int ix = 0; ix < bmCounts.length; ix++) {
            retBMCount.messages += bmCounts[ix].messages;
            retBMCount.bytes += bmCounts[ix].bytes;
        }
        return retBMCount;
    }

    private void checkMonitoringClass(ResourceGroupMonitoringClass monClass) throws PulsarAdminException {
        if (monClass != ResourceGroupMonitoringClass.Publish && monClass != ResourceGroupMonitoringClass.Dispatch) {
            String errMesg = "Unexpected monitoring class: " + monClass;
            throw new PulsarAdminException(errMesg);
        }
    }

    // Fill usage about a particular monitoring class in the transport-manager callback
    // for reporting local stats to other brokers.
    // Returns true if something was filled.
    // Visibility for unit testing.
    protected boolean setUsageInMonitoredEntity(ResourceGroupMonitoringClass monClass, NetworkUsage p) {
        long bytesUsed, messagesUsed;
        boolean sendReport;
        int numSuppressions = 0;
        PerMonitoringClassFields monEntity;

        final int idx = monClass.ordinal();
        monEntity = this.monitoringClassFields[idx];

        monEntity.localUsageStatsLock.lock();
        try {

View on GitHub (pinned to 820761864e)

Solutions

  1. Only pass ResourceGroupMonitoringClass.Publish or .Dispatch to resource-group APIs.
  2. If you added a new monitoring class, extend ResourceGroup to handle it before using it.
  3. Upgrade/downgrade broker and client so enum values match (avoid version skew).
  4. Inspect the config for a typo or unexpected monitoring class value.

Example fix

// before
rg.getConfLimits(ResourceGroupMonitoringClass.Storage);
// after
rg.getConfLimits(ResourceGroupMonitoringClass.Publish);
Defensive patterns

Strategy: type-guard

Validate before calling

if (monClass != ResourceGroupMonitoringClass.Publish
    && monClass != ResourceGroupMonitoringClass.Dispatch) {
  throw new IllegalArgumentException("Unsupported monitoring class: " + monClass);
}

Type guard

boolean isSupportedMonClass(ResourceGroupMonitoringClass c) {
  return c == ResourceGroupMonitoringClass.Publish || c == ResourceGroupMonitoringClass.Dispatch;
}

Try / catch

try {
  stats = rg.getLocalUsageStats(monClass);
} catch (PulsarAdminException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Unexpected monitoring class")) {
    log.warn("Falling back to Dispatch stats for unsupported class " + monClass);
    stats = rg.getLocalUsageStats(ResourceGroupMonitoringClass.Dispatch);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling getConfLimits, getLocalUsageStats (and related cumulative/report stats methods), or incrementLocalUsageStats with a monitoring class other than Publish/Dispatch.

Common situations: New monitoring classes added to the enum without extending ResourceGroup; plugin/extension code passing a custom monitoring class; version skew where a newer enum value from config hits an older broker.

Related errors


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