For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Debug
Find where kagent reports a failure, read the readiness conditions, and work back from a symptom to its cause.
Most kagent failures surface in one place: the readiness conditions on the AgentAgentA Kubernetes custom resource that pairs one AgentTemplate with one Harness. Each side takes either an inline spec or a reference to an existing resource, and the controller compiles the pair into a revision.Learn more. This page explains where to read those conditions, how to tell the real failure from the ones that follow it, and how to work back from the symptoms that report nothing useful on their own.
Where kagent reports status
Two habits from Kubernetes lead nowhere here, so it is worth knowing what reports nothing before you start.
A HarnessHarnessA Kubernetes custom resource defining how an agent is allowed to run: which harness executes the agent, its workload image, and its WorkerPool and snapshot storage. An Agent pairs it with the AgentTemplate that it runs.Learn more has a READY column, but because nothing writes the Harness status, the column is always empty.
kubectl get harness -n kagentExample output:
NAME READY AGE
kagent 30h
An AgentTemplateAgentTemplateA Kubernetes custom resource defining what an agent does: its model, system prompt, tools, skills, and plugins. It runs only once an Agent pairs it with a Harness.Learn more has no status at all, and its list view has no status column, so a healthy template and a broken one look identical.
kubectl get agenttemplate -n kagentExample output:
NAME AGE
assistant 30h
The diagnostic surface is the Agent. An Agent pairs one AgentTemplate with one Harness, and its conditions cover that pairing.
kubectl get agent -n kagentExample output:
NAME READY AGE
assistant True 30h
The READY column reports the status of the Ready condition and nothing else. To find the condition’s reason and message, read the Agent’s conditions directly.
kubectl get agent <name> -n kagent \
-o jsonpath='{range .status.conditions[*]}{.type}{"="}{.status}{" "}{.reason}{": "}{.message}{"\n"}{end}'Example output for a healthy Agent:
Accepted=True Accepted: Agent explicitly selects its template and harness
ResolvedRefs=True Resolved: All runtime references resolved
Compatible=True Compatible: Resolved configuration is compatible with the Harness
Ready=True Ready: ActorTemplate golden snapshot is ready
Read the readiness conditions
The four conditions form a pipeline rather than an unordered set, so their order tells you how far preparation reached before it stopped.
Each condition covers one stage, and a stage runs only when the stage before it succeeded.
| Condition | Stage it covers | A failure here means |
|---|---|---|
Accepted | The Agent selects a template and a Harness. | Nothing. kagent writes this condition only as True, because an Agent references both resources explicitly. |
ResolvedRefs | Every resource that the Agent references was found, including its AgentTemplate, its Harness, its ModelConfig, and any tool servers. | A reference points at something that does not exist, or the controller cannot read it. |
Compatible | The resolved configuration is valid for the Harness. | The configuration asks for something that its Harness does not support. |
Ready | The ActorTemplate’s golden snapshotSnapshotThe stored state that an Actor suspends to, held in object storage. Resuming restores the Actor from its most recent snapshot, which is what makes suspending idle agents cheap.Learn more exists, so Sessions can start from it. | Agent Substrate has not finished capturing the golden snapshot, or capture failed. |
When a stage fails, kagent marks that stage False with the real reason and message, then marks every later stage False with the reason Blocked. Only the first failure describes an actual problem.
Read the first condition that is False and whose reason is not Blocked. Everything after it is a consequence.
In the following example, one missing ModelConfig is the whole problem, and the two conditions after it do not add independent information.
Accepted=True Accepted: Agent explicitly selects its template and harness
ResolvedRefs=False ReferenceResolutionFailed: resolve ModelConfig "does-not-exist": not found
Compatible=False Blocked: blocked by ResolvedRefs
Ready=False Blocked: blocked by ResolvedRefs
The Agent’s status reports two revision fields that answer a different question. desiredRevision is the revisionRevisionThe compiled, immutable output of one Agent, identified by a content digest. A Session runs the revision it was created from for its whole life, so editing the Agent affects only sessions created afterward. that the current spec should produce, and latestSuccessfulRevision is the newest revision that finished preparing. A missing latestSuccessfulRevision means that the Agent was never ready, and two differing values mean that the newest edit is not yet prepared.
The status also reports a warnings list, which shows the compatibility decisions that kagent made without blocking the revision. A warning does not stop an Agent from becoming ready, and the conditions do not report it.
kubectl get agent <name> -n kagent -o jsonpath='{.status.warnings}'A new AgentTemplate never runs
When you create an AgentTemplate directly, nothing prepares it until an Agent references it. The template also has no status for a failure to appear on, so the problem surfaces only when you try to start a conversation.
ERROR:
Code: FailedPrecondition
Message: Agent does not have a ready prepared revision
Check which Agents exist and what each one references.
kubectl get agents -n kagent \
-o jsonpath='{range .items[*]}{.metadata.name}{" template="}{.spec.template.ref.name}{" harness="}{.spec.harnessRef.name}{"\n"}{end}'Example output:
assistant template=assistant harness=kagent
An Agent that defines its behavior inline prints an empty template=, because it has no spec.template.ref to read. If no Agent references your template, create one.
apiVersion: api.kagent.dev/v1alpha3
kind: Agent
metadata:
name: assistant
namespace: kagent
spec:
template:
ref:
name: assistant
harnessRef:
name: kagentNote
An Agent with no conditions at all means that the controller has not reconciled it yet. An Agent with a failing condition means that reconciliation reached that stage and stopped.
An agent turn times out
A turn that fails with a timeout reports the same error regardless of the underlying cause, so this symptom needs elimination rather than reading.
ERROR:
Code: Internal
Message: actor "ai-01a087c0-1d72-775a-9a32-566acac7b685" request timed out
Work through the causes in this order.
Check that the WorkerPoolWorkerPoolA Kubernetes custom resource declaring how many Workers to keep running and which sandbox class they use. An operator must provision one before any Agent can compile.Learn more has ready Workers. A pool with too few Workers produces exactly this error and does not log a capacity message anywhere. To learn how to recognize this problem and size the pool, see Tune Agent Substrate.
kubectl get workerpools -n kagentCheck the model provider. A turn that reaches the model and waits on a slow or unreachable provider also times out. The agent’s own logs name the provider error.
Check the ActorActorThe sandboxed unit of compute, provided by Agent Substrate, that runs a Session's conversation loop. Every Session is backed by one.Learn more state. An Actor stuck in
RESUMING, or sitting inCRASHED, never answers.- To review the list of states, see Suspend and resume.
- To get the current state for every actor, call
GetSubstrateStatus.
An edit to an AgentTemplate has no effect
An edit that appears to do nothing has two possible causes, and the Agent’s conditions distinguish them.
The first cause is a revision that never prepared. Compare the two revision fields on the Agent that references the template. When desiredRevision and latestSuccessfulRevision differ, the edit produces a new revision that is not ready, and the conditions say why.
kubectl get agent <name> -n kagent \
-o jsonpath='{"desired="}{.status.desiredRevision}{" latestSuccessful="}{.status.latestSuccessfulRevision}{"\n"}'The second cause is deliberate. A SessionSessionA running conversation with one Agent. Unlike the resources it is built from, a Session is not a Kubernetes resource: kagent's gRPC API creates it and its PostgreSQL database tracks it.Learn more runs the revision that it was created from for its whole life, so editing an AgentTemplate never changes a conversation that already exists. Create a new Session to pick up the edit.
Collect logs
Once the resource status is exhausted, kagent offers two ways to gather evidence. Read the controller log to locate a single failing call, or collect a bug report to hand somebody else everything at once.
Read the controller log
The controller records every API call with its gRPC status code.
kubectl logs -n kagent deployment/kagent-controllerA failing call appears as an rpc completed line whose grpc_code is not OK, which locates the failure without reading the whole log.
{"time":"2026-09-09T19:23:47.112233381Z","level":"INFO","msg":"rpc completed","component":"grpc","grpc_method":"/lf.a2a.v1.A2AService/SendMessage","rpc_type":"unary","peer":"127.0.0.1:49588","grpc_code":"Internal","duration_ms":5033}
If the default log level does not have enough information, raise the controller’s log level.
controller:
loglevel: debugCollect a bug report
kagent bug-report gathers the whole picture in one command. It writes the kagent resources in a namespace, the names of its secrets, and the logs of every pod into a timestamped directory.
kagent bug-report -n kagentWarning
A bug report contains your resource definitions and pod logs, which can hold prompts, tool output, and other sensitive material. Review the directory before you attach it to an issue.
The report covers kagent’s own resources rather than the Agent Substrate installation underneath it, so add the WorkerPool and the runtime status when a problem looks like a capacity or sandbox issue.
kubectl get workerpools,sandboxconfigs -n kagent -o yaml