apache/hadoop · error · UnsupportedOperationException

Metrics are read-only.

Error message

Metrics are read-only.

What it means

MetricsSourceAdapter implements the JMX DynamicMBean contract, but metrics2 MBeans are read-only views: setAttribute(Attribute) unconditionally throws UnsupportedOperationException('Metrics are read-only.'). No code path mutates a metric through JMX; metrics are produced only by the instrumented component.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/impl/MetricsSourceAdapter.java:124

      throws AttributeNotFoundException, MBeanException, ReflectionException {
    updateJmxCache();
    synchronized(this) {
      Attribute a = attrCache.get(attribute);
      if (a == null) {
        throw new AttributeNotFoundException(attribute +" not found");
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug(attribute +": "+ a);
      }
      return a.getValue();
    }
  }

  @Override
  public void setAttribute(Attribute attribute)
      throws AttributeNotFoundException, InvalidAttributeValueException,
             MBeanException, ReflectionException {
    throw new UnsupportedOperationException("Metrics are read-only.");
  }

  @Override
  public AttributeList getAttributes(String[] attributes) {
    updateJmxCache();
    synchronized(this) {
      AttributeList ret = new AttributeList();
      for (String key : attributes) {
        Attribute attr = attrCache.get(key);
        if (LOG.isDebugEnabled()) {
          LOG.debug(key +": "+ attr);
        }
        ret.add(attr);
      }
      return ret;
    }
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove the write attempt and change the underlying component/config instead of the MBean
  2. If runtime writes are required, expose your own custom MBean rather than a metrics2 source
  3. Guard the client: check MBeanAttributeInfo.isWritable() (always false here) before calling setAttribute

Example fix

// before
mbsc.setAttribute(objectName, new Attribute("NumOps", 5));

// after
MBeanAttributeInfo ai = Arrays.stream(mbsc.getMBeanInfo(objectName).getAttributes())
    .filter(a -> a.getName().equals("NumOps")).findFirst().orElse(null);
if (ai != null && ai.isWritable()) {  // false for metrics2 beans
  mbsc.setAttribute(objectName, new Attribute("NumOps", 5));
}
Defensive patterns

Strategy: validation

Validate before calling

MBeanAttributeInfo ai = Arrays.stream(mbsc.getMBeanInfo(objectName).getAttributes())
    .filter(a -> a.getName().equals(attr)).findFirst().orElse(null);
if (ai != null && ai.isWritable()) {  // always false for metrics2 beans
  mbsc.setAttribute(objectName, new Attribute(attr, value));
}

Try / catch

try {
  mbsc.setAttribute(objectName, new Attribute(attr, value));
} catch (UnsupportedOperationException e) {
  // metrics2 MBeans are read-only by design; configure the component instead
}

Prevention

When it happens

Trigger: Calling MBeanServerConnection.setAttribute, JConsole's set-attribute dialog, or any management client that attempts to write a value on a Hadoop metrics MBean ('Hadoop:service=...,name=...').

Common situations: Ops tooling that assumes all JMX attributes are writable; generic JMX dashboards that offer an edit box for every attribute; attempts to 'pin' a gauge at runtime by writing it through JMX.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/aff77161787f150c. Report an issue: GitHub.