apache/hadoop · error · IllegalArgumentException

The modification time for the record cannot be negative.

Error message

The modification time for the record cannot be negative.

What it means

BaseRecord.validate() also requires dateModified > 0 and throws IllegalArgumentException(ERROR_MSG_MODIFICATION_TIME_NEGATIVE) otherwise. dateModified is stamped on every state store update, so a zero/negative value means the record was produced without the normal write path — legacy persisted rows, hand-built records, or a custom record type that never sets modification time.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/store/records/BaseRecord.java:262

    long deletionTime = getDeletionMs();
    if (isExpired() && deletionTime > 0) {
      long elapsedTime = currentTime - (getDateModified() + getExpirationMs());
      return elapsedTime > deletionTime;
    } else {
      return false;
    }
  }

  /**
   * Validates the record. Called when the record is created, populated from the
   * state store, and before committing to the state store. If validate failed,
   * there throws an exception.
   */
  public void validate() {
    if (getDateCreated() <= 0) {
      throw new IllegalArgumentException(ERROR_MSG_CREATION_TIME_NEGATIVE);
    } else if (getDateModified() <= 0) {
      throw new IllegalArgumentException(ERROR_MSG_MODIFICATION_TIME_NEGATIVE);
    }
  }

  @Override
  public String toString() {
    return getPrimaryKey();
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove or migrate the stale records so they regenerate through the normal write path (heartbeats for membership, config sync for mounts).
  2. In custom record code, default dateModified (and dateCreated) to the current time before validate/put.
  3. After a Hadoop upgrade, reset dev/test state stores instead of reusing pre-upgrade rows.
  4. Audit migration scripts to copy dateCreated/dateModified columns.

Example fix

// before: only creation date set
record.setDateCreated(Time.now());
store.put(record); // throws: modification time negative

// after: set both timestamps
long now = Time.now();
record.setDateCreated(now);
record.setDateModified(now);
store.put(record);
Defensive patterns

Strategy: validation

Validate before calling

if (record.getDateModified() <= 0) {
  record.setDateModified(Time.now());
}
record.validate();

Try / catch

try {
  record.validate();
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("modification time")) {
    record.setDateModified(Time.now()); // dev tooling repair; audit data source in prod
    record.validate();
  } else { throw e; }
}

Prevention

When it happens

Trigger: Deserializing old state store records whose dateModified column is absent/zero; constructing BaseRecord subclasses in code or tests and calling put/validate without setDateModified; migration tooling copying rows without the timestamp columns.

Common situations: Version upgrades carrying forward old state store data; manually crafted records in unit tests; custom record implementations missing the timestamp defaulting.

Related errors


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