apache/flink · error · IllegalStateException

Queryable state name already set

Error message

Queryable state name already set

What it means

setQueryable attempts to register a queryable-state name on the descriptor, but queryableStateName is already non-null from a previous successful call. A descriptor can only carry one queryable name. The method also guards against TTL being enabled (Queryable state is not supported with TTL) before reaching this check.

Solutions

  1. Guard the call with descriptor.isQueryable() (or check getQueryableStateName() == null) before invoking setQueryable.
  2. Ensure setQueryable is called exactly once per descriptor lifecycle; remove duplicate calls.
  3. Note the feature is deprecated since Flink 1.18 and scheduled for removal — prefer another state-query mechanism and drop setQueryable entirely.

Example fix

// before
desc.setQueryable("myState");
...
desc.setQueryable("myState"); // throws on second call

// after
if (!desc.isQueryable()) {
    desc.setQueryable("myState");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!descriptor.isQueryable()) {
    descriptor.setQueryable(queryableStateName);
} else if (!descriptor.getQueryableStateName().equals(queryableStateName)) {
    throw new IllegalStateException(
        "Descriptor already registered as queryable: "
            + descriptor.getQueryableStateName());
}

Type guard

// Guard against duplicate registration
if (descriptor.isQueryable()) {
    // already set; skip or assert the same name
}

Try / catch

try {
    descriptor.setQueryable(name);
} catch (IllegalStateException e) {
    // already registered; ignore if same name, else surface
    if (!name.equals(descriptor.getQueryableStateName())) throw e;
}

Prevention

When it happens

Trigger: Calling setQueryable("name") twice on the same StateDescriptor instance; framework or helper code that registers queryable state and the user also calls it manually; copy-paste duplication of the setQueryable line.

Common situations: Reusable descriptor objects passed to multiple operators where each calls setQueryable; refactoring that leaves a stray setQueryable call alongside a new one; the queryable state feature being deprecated (since 1.18) so users migrating away hit this while toggling settings.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/5f2695c073defdc2. Report an issue: GitHub.

Appendix: source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/state/StateDescriptor.java:245

     * <p>If a name is set, the created state will be published for queries during runtime. The name
     * needs to be unique per job. If there is another state instance published under the same name,
     * the job will fail during runtime.
     *
     * @param queryableStateName State name for queries (unique name per job)
     * @throws IllegalStateException If queryable state name already set
     * @deprecated The Queryable State feature is deprecated since Flink 1.18, and will be removed
     *     in a future Flink major version.
     */
    @Deprecated
    public void setQueryable(String queryableStateName) {
        Preconditions.checkArgument(
                ttlConfig.getUpdateType() == StateTtlConfig.UpdateType.Disabled,
                "Queryable state is currently not supported with TTL");
        if (this.queryableStateName == null) {
            this.queryableStateName =
                    Preconditions.checkNotNull(queryableStateName, "Registration name");
        } else {
            throw new IllegalStateException("Queryable state name already set");
        }
    }

    /**
     * Returns the queryable state name.
     *
     * @return Queryable state name or <code>null</code> if not set.
     * @deprecated The Queryable State feature is deprecated since Flink 1.18, and will be removed
     *     in a future Flink major version.
     */
    @Nullable
    @Deprecated
    public String getQueryableStateName() {
        return queryableStateName;
    }

    /**
     * Returns whether the state created from this descriptor is queryable.

View on GitHub (pinned to 2f3c205e92)