apereo/cas · error · ClientFlowExecutionRepositoryException

Error decoding flow execution

Error message

Error decoding flow execution

What it means

The flow execution encoded in the ClientFlowExecutionKey could not be restored: the transcoder failed to decode/decrypt the key data (tampered, corrupted, expired, or encrypted with different keys), or restoration of the state threw. ClientFlowExecutionRepositoryException wraps that cause. The input at fault is the opaque flow execution key data.

Solutions

  1. Have the user restart the flow with a fresh key (the key is likely stale or corrupted)
  2. Verify webflow cipher/encryption keys are stable across nodes and restarts
  3. Inspect the wrapped cause for decode/decryption specifics
  4. Ensure the key was not truncated in transit (URL length limits, proxies)
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at core/cas-server-core-webflow-api/src/main/java/org/apereo/cas/web/flow/executor/ClientFlowExecutionRepository.java:87 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/453378797437c4d1. Report an issue: GitHub.

Appendix: source

Thrown at core/cas-server-core-webflow-api/src/main/java/org/apereo/cas/web/flow/executor/ClientFlowExecutionRepository.java:87

    public FlowExecutionLock getLock(final FlowExecutionKey key) throws FlowExecutionRepositoryException {
        return NOOP_LOCK;
    }

    @Override
    public FlowExecution getFlowExecution(final FlowExecutionKey key) throws FlowExecutionRepositoryException {
        if (key instanceof final ClientFlowExecutionKey clientFlowExecutionKey) {
            try {
                val encoded = clientFlowExecutionKey.getData();
                val state = (SerializedFlowExecutionState) determineTranscoder().decode(encoded);

                if (webflowProperties.getSession().isPinToSession()) {
                    verifyWebflowSessionIsCorrectlyPinned(state);
                }
                val conversationScope = state.getConversationScope();
                val flow = flowDefinitionLocator.getFlowDefinition(state.getFlowId());
                return flowExecutionFactory.restoreFlowExecution(state.getExecution(), flow, key, conversationScope, this.flowDefinitionLocator);
            } catch (final Exception e) {
                throw new ClientFlowExecutionRepositoryException("Error decoding flow execution", e);
            }
        }
        throw new IllegalArgumentException("Expected instance of ClientFlowExecutionKey but got " + key.getClass().getName());
    }


    @Override
    public void putFlowExecution(final FlowExecution flowExecution) throws FlowExecutionRepositoryException {
    }

    @Override
    public void removeFlowExecution(final FlowExecution flowExecution) throws FlowExecutionRepositoryException {
    }

    @Override
    public FlowExecutionKey getKey(final FlowExecution execution) {
        try {
            if (webflowProperties.getSession().isPinToSession()) {

View on GitHub (pinned to e7288fc434)