eclipse-vertx/vert.x · error · IllegalArgumentException

Can't register a system codec

Error message

Can't register a system codec

What it means

Vert.x ships built-in system codecs (null, ping, pong, reply failures, ClusterSerializable, Serializable, etc.) identified by systemCodecID() != -1. CodecManager.checkSystemCodec throws this IllegalArgumentException to forbid user registration of any codec claiming a system codec ID, protecting the internal codec table from corruption.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/eventbus/impl/CodecManager.java:172

    defaultCodecMap.put(clazz, codec);
    userCodecMap.put(codec.name(), codec);
  }

  public void unregisterDefaultCodec(Class clazz) {
    Objects.requireNonNull(clazz);
    MessageCodec codec = defaultCodecMap.remove(clazz);
    if (codec != null) {
      userCodecMap.remove(codec.name());
    }
  }

  public MessageCodec[] systemCodecs() {
    return systemCodecs;
  }

  private void checkSystemCodec(MessageCodec codec) {
    if (codec.systemCodecID() != -1) {
      throw new IllegalArgumentException("Can't register a system codec");
    }
  }

  private MessageCodec[] codecs(MessageCodec... codecs) {
    MessageCodec[] arr = new MessageCodec[codecs.length];
    for (MessageCodec codec : codecs) {
      arr[codec.systemCodecID()] = codec;
    }
    return arr;
  }

  public void clusterSerializableCheck(Function<String, Boolean> classNamePredicate) {
    this.clusterSerializableCheck = Objects.requireNonNull(classNamePredicate);
  }

  public boolean acceptClusterSerializable(String className) {
    return clusterSerializableCheck.apply(className);
  }

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Override systemCodecID() in your custom codec to return -1.
  2. If you need a system codec's behavior, wrap it in your own codec class with systemCodecID() = -1 rather than registering the system codec itself.
  3. Register the message type with a normal user codec name instead of attempting to reuse built-in codec IDs.

Example fix

// before
@Override public int systemCodecID() { return 0; } // reserved for system codecs
// after
@Override public int systemCodecID() { return -1; }
Defensive patterns

Strategy: validation

Validate before calling

if (codec.systemCodecID() != -1) {
  throw new IllegalArgumentException("custom codec must return -1 from systemCodecID()");
}
bus.registerCodec(codec);

Try / catch

try {
  bus.registerCodec(codec);
} catch (IllegalArgumentException e) {
  // system codec rejected; fix systemCodecID()
}

Prevention

When it happens

Trigger: Implementing a custom MessageCodec whose systemCodecID() returns 0 or another non -1 value, then calling registerCodec or registerDefaultCodec with it.

Common situations: Copying the source of a built-in codec (e.g. NullMessageCodec) as a template and forgetting to override systemCodecID() to return -1; implementing the MessageCodec interface by delegating to a system codec.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/3c0bd8afe0a58eac. Report an issue: GitHub.