Steps
1
Look at the run, not the log
FAILURE. Every node behind it, and any node that had not started when the run failed, ends UPSTREAM_FAILED, which means “not reached because the run failed”. The first terminal that fails ends the run and cancels the other branches. Find the node with FAILURE or TIMED_OUT, read its reason, then its logs (yukta-cli logs <session-id> <execution-id> --node <node> --tail 50). A node with several parents fails when one parent fails; set engine.trigger to ALL_DONE or ONE_SUCCESS if it should carry on. See Handle failures.2
Match the symptom
Use the table below, then read the section it names.
3
Check what was refused, and by whom
A refused control command is in the audit with its reason:
Symptoms
A run stays QUEUED
A run isQUEUED while it waits for a slot. Check:
yukta.executions.runningagainstyukta.execution.max-concurrent,max-concurrent-per-sessionandmax-concurrent-per-workflow.- Whether running runs are stuck. A run holds its slot until it ends, and a paused run keeps its slot with its clocks frozen. Stop or resume stuck runs.
- The queue order: higher priority first, then the session with the fewest running runs, then arrival. Change a waiting run’s priority with
yukta-cli workflow executions priority <execution-id> <n>.
yukta-cli scheduler limits set (ADMIN). Set yukta.execution.queue-timeout so a start that waits too long ends TIMED_OUT. See Tune capacity and limits.
A node or run times out
TIMED_OUT has one cause per clock:
Pausing freezes every clock, so a pause never causes a timeout. See How time limits work.
A command is rejected with 403
Several checks answer403:
- Role. A
VIEWERcannot change anything. AnOPERATORreaches only paths under/api/executions/and/api/workflow/. Defining workflows and changing scheduler limits needADMIN. - Session list. A key limited to sessions reaches only its own.
- Host or Origin. With no key set, an unknown
Host, or a foreignOriginon a changing request, is refused with no body. - A supervisor. A supervisor that reviews commands can refuse one with
403(CONTROL_REJECTED). A person’s command to a run that a supervisor owns gets409(CONTROLLED_BY_SUPERVISOR) unless the supervisor’s operator access allows it. The CLI exits with code 6 for both. Checkyukta-cli ownership --session <s> --workflow <w>and the audit.
yukta-cli controlbus audit --execution <id>. See Secure the server.
Resume is refused
POST /api/executions/{id}/recover (and yukta-cli workflow executions recover) answers 409 when:
- The run was not aborted. Only a run that a restart aborted can be resumed.
- The run is being resumed, or was already resumed. A run resumes once.
- The workflow changed since the run started.
- The start payload was not recorded.
- Every node had already finished.
404 when the run is unknown (for example after a restart with the in-memory log) or its workflow no longer exists, and 429 when the new run gets no slot (nothing is recorded, so try again). Resume needs a durable execution log and a durable checkpoint store. See Persist sessions.
Approvals disappear after a restart
Open approval waits live in memory. After a restart or a high availability takeover, an open request is gone, and it reappears only when its node waits again, for example in a resumed run. An approval that was already answered is recorded with the checkpoints, and a resumed run reuses the answer. Input requests can be kept in PostgreSQL withyukta.input.store-type=postgres.
A process node is refused
PROCESS_EXECUTOR refuses with one of these messages:
On a placed node, set the allow-list on the worker. See Secure the server.
The server refuses to start
The message reads “Refusing to listen on ’…’ without an API key”. The server refuses any address but loopback unless a key exists. Setyukta.api-keys (the container image listens on 0.0.0.0, so it always needs YUKTA_API_KEYS_0_NAME, _KEY and _ROLE), or set YUKTA_SERVER_ADDRESS=127.0.0.1. See Deploy Yukta.
PostgreSQL does not start
The server applies schema migrations first and does not start if one fails. Check:- Both URLs are set:
spring.flyway.urlfor migrations (jdbc:postgresql://...) andspring.r2dbc.urlfor run-time access (r2dbc:postgresql://...). They are different URL forms for the same database. - The migration account may change the schema.
- The
postgresprofile is active, and the build used-Pyukta.persistence=postgres. See Persist sessions.
Verify it worked
Repeat the call that failed. A start returns an execution id, a refused command no longer appears inyukta-cli controlbus audit, or the server logs “Started” and GET /actuator/health returns {"status":"UP"}. If the symptom is not in the table, copy the exact error message, the status code and the execution id into an issue on the repository.