apache/skywalking · warning · IllegalArgumentException

invalid_limits

invalid_limits

Error message

recordCap must be > 0, got {recordCap}

What it means

SessionLimits' constructor enforces a lower bound on recordCap: it must be strictly positive. recordCap caps how many raw records (spans/logs) a DSL debugging session retains; zero or negative values are meaningless for a capture buffer, so the constructor rejects them immediately with an invalid_limits IllegalArgumentException.

Source

Thrown at oap-server/server-admin/dsl-debugging/src/main/java/org/apache/skywalking/oap/server/admin/dsl/debugging/session/SessionLimits.java:68

    /**
     * Hard upper bound on the per-session retention window (1 hour). Sessions
     * are operator-driven and short-lived by design; a runaway retention would
     * keep payload JSON pinned in heap long after the operator has left.
     */
    public static final long MAX_RETENTION_MILLIS = 60L * 60 * 1000;

    public static final SessionLimits DEFAULT =
        new SessionLimits(MAX_RECORD_CAP, 5L * 60 * 1000, Granularity.DEFAULT);

    private final int recordCap;
    private final long retentionMillis;
    private final Granularity granularity;

    public SessionLimits(final int recordCap, final long retentionMillis,
                         final Granularity granularity) {
        if (recordCap <= 0) {
            throw new IllegalArgumentException(
                "recordCap must be > 0, got " + recordCap);
        }
        if (recordCap > MAX_RECORD_CAP) {
            throw new IllegalArgumentException(
                "recordCap " + recordCap + " exceeds hard cap " + MAX_RECORD_CAP);
        }
        if (retentionMillis <= 0) {
            throw new IllegalArgumentException(
                "retentionMillis must be > 0, got " + retentionMillis);
        }
        if (retentionMillis > MAX_RETENTION_MILLIS) {
            throw new IllegalArgumentException(
                "retentionMillis " + retentionMillis + " exceeds hard cap " + MAX_RETENTION_MILLIS);
        }
        this.recordCap = recordCap;
        this.retentionMillis = retentionMillis;
        this.granularity = granularity == null ? Granularity.DEFAULT : granularity;
    }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Omit recordCap from the request to use the default, or send a positive value (1..MAX_RECORD_CAP)
  2. Fix client code that zero-fills optional numeric fields to omit them instead
  3. Treat 'unlimited' as 'omit the field', never as 0

Example fix

// before
{"recordCap": 0, "retentionMillis": 300000}
// after
{"retentionMillis": 300000}
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: only send positive recordCap, omit otherwise
Integer cap = requestedCap != null && requestedCap > 0 ? requestedCap : null;

Type guard

function isValidRecordCap(v: unknown): boolean {
  return v === undefined || (Number.isInteger(v) && v > 0 && v <= MAX_RECORD_CAP);
}

Try / catch

Treat the invalid_limits HTTP error as a client bug: fix the payload generator; catching/retrying adds nothing since the server will reject the same value again.

Prevention

When it happens

Trigger: POST /dsl-debugging/session with a JSON body containing "recordCap": 0 or a negative number; or constructing SessionLimits programmatically with 0. Any non-positive value hits this branch before the upper-cap check.

Common situations: Client scripts defaulting numeric fields to 0 and sending them unconditionally; misreading '0' as 'unlimited'; copy-pasting a template that zero-fills optional fields.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/6147a2e7094d9cad. Report an issue: GitHub.