Skip to main content
Use this when something on a running server does not work: a start is refused, a run does not finish, a command is rejected, or the server will not start. Prerequisites: a key for the server (see Secure the server). For every status code the REST API returns, see Errors.

Steps

1

Look at the run, not the log

Only the node that failed ends 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 is QUEUED while it waits for a slot. Check:
  1. yukta.executions.running against yukta.execution.max-concurrent, max-concurrent-per-session and max-concurrent-per-workflow.
  2. 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.
  3. 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>.
To raise limits without a restart, use 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 answer 403:
  • Role. A VIEWER cannot change anything. An OPERATOR reaches only paths under /api/executions/ and /api/workflow/. Defining workflows and changing scheduler limits need ADMIN.
  • Session list. A key limited to sessions reaches only its own.
  • Host or Origin. With no key set, an unknown Host, or a foreign Origin on 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 gets 409 (CONTROLLED_BY_SUPERVISOR) unless the supervisor’s operator access allows it. The CLI exits with code 6 for both. Check yukta-cli ownership --session <s> --workflow <w> and the audit.
The audit entry for a refused command shows the command and the reason: 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.
It answers 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 with yukta.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. Set yukta.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.url for migrations (jdbc:postgresql://...) and spring.r2dbc.url for run-time access (r2dbc:postgresql://...). They are different URL forms for the same database.
  • The migration account may change the schema.
  • The postgres profile 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 in yukta-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.