Temporal Configuration
This guide covers everything you need to configure Temporal for AgentVisor™, from local development to production deployments.
Temporal Basics
Temporal provides the foundation for AgentVisor's durable execution model. Understanding what Temporal offers helps you configure it effectively.
What Temporal Provides
- Durability: Workflow state survives process crashes, node failures, and deployments
- Reliability: Automatic retries and failure handling for agent activities
- Visibility: Workflow history inspection and real-time state queries
- Signals: Async communication with running workflows (used for interrupts)
How AgentVisor Uses Temporal
AgentVisor's OpenAPI/REST transport is implemented using Temporal workflows:
| API Concept | Temporal Implementation |
|---|---|
| Thread | Workflow instance (ThreadWorkflow) |
| Run | Workflow Update + Activity execution |
| Checkpoint | Workflow state (persisted in history) |
| Interrupt | Workflow signal + pending state |
Each conversation thread is a Temporal workflow, and agent executions are Temporal activities. This means all conversation state lives in Temporal—AgentVisor instances are stateless.
For architectural details, see Temporal Integration.
Connection Configuration
Basic Configuration
Connect AgentVisor to a Temporal server:
temporal:
target: localhost:7233 # Temporal server address
namespace: default # Temporal namespace
task_queue: agentvisor # Task queue name
Or via environment variables:
export AGENTVISOR_TEMPORAL_TARGET=localhost:7233
export AGENTVISOR_TEMPORAL_NAMESPACE=default
export AGENTVISOR_TEMPORAL_TASK_QUEUE=agentvisor
Configuration Reference
| Variable | Default | Description |
|---|---|---|
AGENTVISOR_TEMPORAL_TARGET | localhost:7233 | Temporal server address (host:port) |
AGENTVISOR_TEMPORAL_NAMESPACE | default | Temporal namespace |
AGENTVISOR_TEMPORAL_TASK_QUEUE | agentvisor | Task queue for workflow activities |
AGENTVISOR_TEMPORAL_MAX_RUN_HISTORY | 100 | Max runs to retain per thread |
AGENTVISOR_TEMPORAL_MAX_CHECKPOINT_HISTORY | 1 | Max checkpoints per run |
Namespace and Task Queue Strategy
Critical: Unique Namespace + Task Queue Per Agent
Each agent deployment must use a unique namespace+task_queue combination. This prevents:
- Workflow routing conflicts: Different agents processing each other's workflows
- Activity confusion: Wrong agent code executing activities
- State corruption: Different agent schemas being applied incorrectly
# Agent A deployment
temporal:
namespace: mycompany-prod
task_queue: chatbot-agent
# Agent B deployment (different queue!)
temporal:
namespace: mycompany-prod
task_queue: research-agent
Naming Conventions
Recommended naming patterns:
| Pattern | Example | Use Case |
|---|---|---|
{org}-{env} | acme-prod | Namespace per organization+environment |
{agent}-{version} | chatbot-v2 | Task queue per agent version |
{team}-{agent} | platform-qa-agent | Team-based organization |
Multi-Environment Patterns
Separate environments with namespaces:
# Development
AGENTVISOR_TEMPORAL_NAMESPACE=myagent-dev
AGENTVISOR_TEMPORAL_TASK_QUEUE=myagent
# Staging
AGENTVISOR_TEMPORAL_NAMESPACE=myagent-staging
AGENTVISOR_TEMPORAL_TASK_QUEUE=myagent
# Production
AGENTVISOR_TEMPORAL_NAMESPACE=myagent-prod
AGENTVISOR_TEMPORAL_TASK_QUEUE=myagent
This provides complete isolation between environments and enables independent scaling.
Search Attributes Setup
AgentVisor uses Temporal search attributes for efficient thread discovery. These must be created once per Temporal cluster (self-hosted) or namespace (Temporal Cloud).
Required Search Attributes
| Attribute | Type | Purpose |
|---|---|---|
MavSystemMetadata | KeywordList | Internal: Principal, GraphName, Ephemeral status |
MavMetadata | KeywordList | User-defined key:value pairs for filtering |
MavThreadStatus | Keyword | Thread status: idle, busy, interrupted, error |
Self-Hosted: CLI Setup
# Create search attributes (run once per cluster)
temporal operator search-attribute create \
--name MavSystemMetadata \
--type KeywordList
temporal operator search-attribute create \
--name MavMetadata \
--type KeywordList
temporal operator search-attribute create \
--name MavThreadStatus \
--type Keyword
Temporal Cloud: UI Setup
- Log in to Temporal Cloud
- Navigate to your namespace
- Go to Namespace Settings > Search Attributes
- Click Add Search Attribute for each:
- Name:
MavSystemMetadata, Type:KeywordList - Name:
MavMetadata, Type:KeywordList - Name:
MavThreadStatus, Type:Keyword
- Name:
Verification
Verify search attributes are configured:
# List search attributes
temporal operator search-attribute list
# Expected output should include:
# MavSystemMetadata KeywordList
# MavMetadata KeywordList
# MavThreadStatus Keyword
Using Search Attributes
Search for threads via the API:
# Find threads by user
curl -X POST http://localhost:8090/threads/search \
-H "Content-Type: application/json" \
-d '{"metadata": {"user": "alice"}}'
# Find interrupted threads
curl -X POST http://localhost:8090/threads/search \
-H "Content-Type: application/json" \
-d '{"status": "interrupted"}'
Self-Hosted Temporal Configuration
Development Server
For local development, use Temporal's development server:
temporal server start-dev
temporal operator search-attribute create --name MavSystemMetadata --type KeywordList
temporal operator search-attribute create --name MavMetadata --type KeywordList
temporal operator search-attribute create --name MavThreadStatus --type Keyword
# Access Web UI at http://localhost:8233
The dev server includes:
- In-memory storage (data lost on restart)
- Web UI for workflow inspection
- Pre-configured for development
Production Cluster Considerations
For production self-hosted Temporal:
Database backend:
- PostgreSQL (recommended for most deployments)
- MySQL (alternative SQL option)
- Cassandra (for very large scale)
TLS configuration:
temporal:
target: temporal.internal:7233
# mTLS settings for self-hosted
auth:
type: mtls
mtls:
ca_file: /etc/ssl/temporal/ca.crt
cert_file: /etc/ssl/temporal/client.crt
key_file: /etc/ssl/temporal/client.key
Or via environment:
export AGENTVISOR_TEMPORAL_AUTH_TYPE=mtls
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_FILE=/etc/ssl/temporal/ca.crt
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_FILE=/etc/ssl/temporal/client.crt
export AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_FILE=/etc/ssl/temporal/client.key
Cluster scaling:
- Scale history service for more concurrent workflows
- Scale frontend service for more API connections
- See Temporal Server documentation
Temporal Cloud Configuration
Temporal Cloud provides managed, production-ready Temporal infrastructure. AgentVisor supports two authentication methods.
API Key Authentication (Recommended)
API keys are the simplest way to connect to Temporal Cloud.
Step 1: Create an API Key
- Log in to Temporal Cloud
- Go to Settings > API Keys
- Click Create API Key
- Copy the key (you won't see it again)
Step 2: Configure AgentVisor
temporal:
target: my-namespace.account-id.tmprl.cloud:7233
namespace: my-namespace.account-id
auth:
type: api_key
# Set API key via environment variable (recommended)
export AGENTVISOR_TEMPORAL_TARGET=my-namespace.account-id.tmprl.cloud:7233
export AGENTVISOR_TEMPORAL_NAMESPACE=my-namespace.account-id
export AGENTVISOR_TEMPORAL_AUTH_TYPE=api_key
export AGENTVISOR_TEMPORAL_AUTH_API_KEY=your-api-key-here
Never commit API keys to version control. Always use environment variables or a secrets manager.
mTLS Authentication
mTLS uses client certificates for authentication, providing stronger security guarantees.
Step 1: Generate Certificates
# Generate private key
openssl genrsa -out client.key 4096
# Generate CSR
openssl req -new -key client.key -out client.csr \
-subj "/CN=my-namespace.account-id"
# Upload CSR to Temporal Cloud and download signed certificate
# See: https://docs.temporal.io/cloud/certificates
Or use tcld (Temporal Cloud CLI):
tcld namespace accepted-client-ca add \
--namespace my-namespace.account-id \
--ca-certificate-file ca.pem
Step 2: Configure AgentVisor
File-based certificates:
temporal:
target: my-namespace.account-id.tmprl.cloud:7233
namespace: my-namespace.account-id
auth:
type: mtls
mtls:
cert_file: /path/to/client.crt
key_file: /path/to/client.key
export AGENTVISOR_TEMPORAL_AUTH_TYPE=mtls
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_FILE=/path/to/client.crt
export AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_FILE=/path/to/client.key
Base64-Encoded Certificates
For environments where file paths aren't convenient (e.g., Kubernetes secrets):
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_DATA=$(base64 -w0 client.crt)
export AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_DATA=$(base64 -w0 client.key)
The -w0 flag is GNU coreutils syntax (Linux). On macOS, use base64 without the flag—macOS base64 doesn't wrap output by default:
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_DATA=$(base64 client.crt)
export AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_DATA=$(base64 client.key)
Or in config:
temporal:
auth:
type: mtls
mtls:
cert_data: "LS0tLS1CRUdJTi..." # base64-encoded cert
key_data: "LS0tLS1CRUdJTi..." # base64-encoded key
Custom CA Certificate
If using a private CA:
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_FILE=/path/to/ca.crt
Or base64-encoded inline (useful for Kubernetes secrets):
export AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_DATA=$(base64 -w0 ca.crt)
temporal:
auth:
type: mtls
mtls:
ca_data: "LS0tLS1CRUdJTi..." # base64-encoded CA certificate
Kubernetes Secret Example
apiVersion: v1
kind: Secret
metadata:
name: temporal-cloud-creds
type: Opaque
data:
api-key: <base64-encoded-api-key>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: agentvisor
spec:
template:
spec:
containers:
- name: agentvisor
image: my-agent:v1
env:
- name: AGENTVISOR_TEMPORAL_TARGET
value: my-namespace.account-id.tmprl.cloud:7233
- name: AGENTVISOR_TEMPORAL_NAMESPACE
value: my-namespace.account-id
- name: AGENTVISOR_TEMPORAL_AUTH_TYPE
value: api_key
- name: AGENTVISOR_TEMPORAL_AUTH_API_KEY
valueFrom:
secretKeyRef:
name: temporal-cloud-creds
key: api-key
Authentication Environment Variables Reference
| Variable | Description |
|---|---|
AGENTVISOR_TEMPORAL_AUTH_TYPE | Auth type: api_key or mtls |
AGENTVISOR_TEMPORAL_AUTH_API_KEY | Temporal Cloud API key |
AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_FILE | Path to client certificate |
AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_FILE | Path to client private key |
AGENTVISOR_TEMPORAL_AUTH_MTLS_CERT_DATA | Base64-encoded client certificate |
AGENTVISOR_TEMPORAL_AUTH_MTLS_KEY_DATA | Base64-encoded client private key |
AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_FILE | Path to custom CA certificate |
AGENTVISOR_TEMPORAL_AUTH_MTLS_CA_DATA | Base64-encoded custom CA certificate |
AGENTVISOR_TEMPORAL_AUTH_MTLS_SERVER_NAME | TLS server name override |
Payload Encryption (Codec Configuration)
AgentVisor can encrypt all data stored in Temporal workflow history—including checkpoints, agent state, and run inputs/outputs—using AES-256-GCM encryption.
Why Encrypt Workflow Payloads?
- Data at rest protection: Temporal server stores only ciphertext
- Compliance requirements: Meet security requirements for sensitive data
- Multi-tenant isolation: Each deployment can use different encryption keys
Enabling Encryption
temporal:
codec:
enabled: true
type: aes256
export AGENTVISOR_TEMPORAL_CODEC_ENABLED=true
export AGENTVISOR_TEMPORAL_CODEC_TYPE=aes256
export AGENTVISOR_TEMPORAL_CODEC_AES256_PASSWORD=your-secure-password
export AGENTVISOR_TEMPORAL_CODEC_AES256_SALT=unique-deployment-salt
AES-256 Provider Configuration
| Variable | Default | Description |
|---|---|---|
AGENTVISOR_TEMPORAL_CODEC_AES256_PASSWORD | — | Encryption password (required) |
AGENTVISOR_TEMPORAL_CODEC_AES256_SALT | — | PBKDF2 salt for key derivation, unique per deployment (required) |
AGENTVISOR_TEMPORAL_CODEC_AES256_ITERATIONS | 600000 | PBKDF2 iteration count (rejected below 100,000) |
Complete YAML Configuration
temporal:
target: localhost:7233
namespace: default
task_queue: agentvisor
codec:
enabled: true
type: aes256
aes256:
password: "${CODEC_PASSWORD}" # Use env var for secrets
salt: "unique-deployment-salt"
iterations: 600000
server:
enabled: true
listen_addr: "127.0.0.1:8091"
allowed_origins:
- "http://localhost:8233" # Temporal Web UI
auth:
enabled: true
oidc_issuer: "https://idp.example.com"
oidc_audience: "agentvisor-codec"
Password Management Best Practices
If the encryption password is lost, encrypted workflow data cannot be recovered. Store passwords securely using a secrets manager.
- Use a strong, unique password (32+ characters recommended)
- Store in a secrets manager (HashiCorp Vault, AWS Secrets Manager, etc.)
- Salt is required and must be unique per deployment; startup fails without one
- Keep 600,000+ iterations for PBKDF2 (OWASP recommended minimum; values below 100,000 are rejected)
Codec Server for Temporal Web UI
Without a codec server, Temporal Web UI shows only encrypted binary data. Enable the codec server to decrypt payloads in the UI:
The codec server receives a payload's namespace (via the X-Namespace header, used below for policy authorization) but never its workflow ID — Temporal's Web UI and CLI don't send workflow ID to codec server endpoints. Decrypting a binary/encrypted-v2 payload requires both the namespace and workflow ID it was encrypted under, so the missing workflow ID means the codec server can only decrypt payloads that were encrypted without workflow binding. New workflow activity is encrypted bound to its namespace and workflow ID and will still show as encrypted binary data in the Web UI — see Payload Encryption > Workflow Binding.
/decode is a decryption oracle — secure it before widening its reachThe codec server's /decode endpoint takes ciphertext and returns the decrypted workflow payload — agent inputs, outputs, and checkpoints. Anyone who can reach the listener can decrypt anything the codec has ever encrypted. listen_addr defaults to loopback (127.0.0.1:8091) so the endpoint is confined to the local host unless you deliberately widen it.
Listing https://cloud.temporal.io (or any other external UI origin) in allowed_origins means the endpoint must be reachable from outside the host — CORS alone does not authenticate the caller, it only tells browsers which pages are allowed to try. Before doing this, set auth.enabled: true below so /decode and /encode require a valid Bearer token, and configure your PolicyDomain to authorize the X-Namespace the request names (see Policy Enforcement). Without both, any page that can send a same-origin or CORS-permitted request decrypts your workflow history.
When AGENTVISOR_ENV=production is set, startup is refused outright if the codec server is enabled with auth.enabled: false — the same hard-block applied to api.auth.test_mode and authz.type: allowall.
temporal:
codec:
server:
enabled: true
listen_addr: "127.0.0.1:8091" # widen only if the UI runs off-host
allowed_origins:
- "http://localhost:8233" # Dev server
auth:
enabled: true
oidc_issuer: "https://idp.example.com"
oidc_audience: "agentvisor-codec"
export AGENTVISOR_TEMPORAL_CODEC_SERVER_ENABLED=true
export AGENTVISOR_TEMPORAL_CODEC_SERVER_LISTEN_ADDR=127.0.0.1:8091
export AGENTVISOR_TEMPORAL_CODEC_SERVER_ALLOWED_ORIGINS=http://localhost:8233
export AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_ENABLED=true
export AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_ISSUER=https://idp.example.com
export AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_AUDIENCE=agentvisor-codec
Configure Temporal Web UI to use the codec server:
- Open Temporal Web UI
- Go to Settings (gear icon)
- Set Codec Server to
http://localhost:8091 - Enable Pass the user access token so the Web UI forwards the operator's login token in the
Authorizationheader — required whenauth.enabledis set - Refresh the page
Authorizing namespaces: Every request the Web UI sends includes an X-Namespace header naming the namespace being viewed. When auth.enabled is set, AgentVisor authenticates the Bearer token and then asks your PolicyDomain to authorize mrn:agentvisor:temporal:<namespace> for the resulting principal — grant this only to operators who should be able to decrypt that namespace's payloads. A caller with a valid token but no grant for the requested namespace receives 403; a caller with no token (or an invalid one) receives 401 before the codec runs at all.
Codec Server Environment Variables
| Variable | Default | Description |
|---|---|---|
AGENTVISOR_TEMPORAL_CODEC_SERVER_ENABLED | false | Enable HTTP codec server |
AGENTVISOR_TEMPORAL_CODEC_SERVER_LISTEN_ADDR | 127.0.0.1:8091 | Server listen address (loopback by default) |
AGENTVISOR_TEMPORAL_CODEC_SERVER_ALLOWED_ORIGINS | — | CORS allowed origins (comma-separated) |
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_ENABLED | false | Require a valid Bearer token on /encode and /decode |
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_ISSUER | — | OIDC issuer used to validate the Web UI's forwarded token |
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_AUDIENCE | — | Expected OIDC aud claim |
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_JWKS_URL | — | Override JWKS URL (must be https; loopback exempt) |
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_OIDC_ALLOW_INSECURE | false | Permit plaintext http:// OIDC endpoints — never in production |
AGENTVISOR_TEMPORAL_CODEC_SERVER_AUTH_ALLOW_CREDENTIALS | false | Set Access-Control-Allow-Credentials, enabling the Web UI's cookie-based auth mode |
For encryption algorithm details, see Payload Encryption.
History Management
Long-running agent conversations can accumulate large workflow histories. AgentVisor uses Temporal's Continue-As-New mechanism to manage this.
Continue-As-New Mechanism
When history thresholds are reached:
- Workflow completes with its current state
- A new workflow execution starts with the same thread ID
- State is transferred to the new execution
- Older runs are pruned to configured limits
This happens transparently—the thread ID remains stable for API clients.
Configuration
temporal:
max_run_history: 100 # Runs retained per thread
max_checkpoint_history: 10 # Checkpoints retained per run
export AGENTVISOR_TEMPORAL_MAX_RUN_HISTORY=100
export AGENTVISOR_TEMPORAL_MAX_CHECKPOINT_HISTORY=10
Why This Matters
Without history management:
- Workflow history grows unbounded
- Query performance degrades
- Temporal storage costs increase
- Workflow replay becomes slow
With these limits:
- History size stays bounded
- Performance remains consistent
- Costs are predictable
- Recent conversation context is preserved
Tuning Guidance
| Setting | Low Value | High Value | Trade-off |
|---|---|---|---|
max_run_history | 10 | 1000 | Less history vs. more conversation context |
max_checkpoint_history | 1 | 100 | Less granular replay vs. more resume points |
Recommended starting values:
max_run_history: 100— Keeps last 100 user interactionsmax_checkpoint_history: 10— Allows reasonable checkpoint granularity
Bounding put_writes-Driven History Growth
max_run_history and max_checkpoint_history bound in-memory state, but they don't bound
workflow history growth within a single execution. LangGraph's checkpointer calls
put_writes once per completed task per superstep, and each call is a full Update round trip
(roughly 5 history events). A graph with many parallel tasks per superstep can accumulate
history quickly within one run, and by default the only thing that stops it is Temporal's own
GetContinueAsNewSuggested heuristic — which reacts to total history size/duration, not
specifically to put_writes volume, and can let history grow substantially before it fires.
max_put_writes_per_execution (AGENTVISOR_TEMPORAL_MAX_PUT_WRITES_PER_EXECUTION) forces a
Continue-As-New after this many put_writes Update calls within a single workflow execution.
It's 0 (disabled) by default, since the right threshold is workload-dependent — set it well
below Temporal's history soft limit for graphs with many parallel tasks per superstep, so any
single Continue-As-New transition stays small and predictable:
temporal:
max_put_writes_per_execution: 500 # 0 = disabled (default)
export AGENTVISOR_TEMPORAL_MAX_PUT_WRITES_PER_EXECUTION=500
Testing Mid-Run Continue-As-New
force_continue_as_new_during_active_run (AGENTVISOR_TEMPORAL_FORCE_CONTINUE_AS_NEW_DURING_ACTIVE_RUN)
forces a Continue-As-New while a run is actively executing, instead of only between runs.
It exists to exercise the mid-run CAN path deterministically in tests — leave it disabled
(the default) in production.
Enabling it changes what POST /threads/{id}/runs returns while a client is waiting
(wait=): the active run is cancelled to make way for Continue-As-New, so the immediate
response reports a transient status: "interrupted" with
error: "run interrupted by continue-as-new" rather than the run's final status. The run
then auto-resumes under the same run_id in the new workflow execution. A client that needs
the real outcome must poll GET /threads/{id}/runs/{run_id} (or use an SDK helper that
already does this, e.g. the Python integration test client's wait_for_run) until the run
reaches a terminal status, rather than trusting the immediate wait= response.
This setting is also pinned per thread: a thread's whole Continue-As-New chain keeps whichever value was in effect when the thread was first created. Toggling it in your running config only changes behavior for threads created afterward — an existing thread keeps its original setting for the rest of its lifetime, including across further Continue-As-New cycles.
Troubleshooting
Connection Issues
Error: "connection refused"
- Verify Temporal server is running:
temporal server start-dev - Check target address format:
host:port(not URL) - For Temporal Cloud:
<namespace>.<account-id>.tmprl.cloud:7233
Error: "dial tcp: lookup ... no such host"
- DNS resolution failing—verify hostname is correct
- In Kubernetes, ensure Temporal service is accessible
Authentication Failures
API Key errors:
Error: invalid API key
- Verify the key is correct and not expired
- Check the key has permissions for the namespace
- Ensure
AGENTVISOR_TEMPORAL_AUTH_TYPE=api_keyis set
mTLS errors:
Error: x509: certificate signed by unknown authority
- Certificate not signed by a CA trusted by Temporal Cloud
- Check certificate chain:
openssl verify -CAfile ca.crt client.crt
Error: x509: certificate has expired
- Certificate expired:
openssl x509 -in client.crt -noout -dates - Generate a new certificate
TLS handshake failures:
- Ensure server name matches:
AGENTVISOR_TEMPORAL_AUTH_MTLS_SERVER_NAME - For Temporal Cloud:
<namespace>.<account-id>.tmprl.cloud
Warning: connecting without auth:
WARN connecting to Temporal Cloud without authentication - this will likely fail
- Connecting to
*.tmprl.cloudwithout auth configured - Set
AGENTVISOR_TEMPORAL_AUTH_TYPEtoapi_keyormtls
Search Attribute Errors
Error: "search attribute MavSystemMetadata is not defined"
- Search attributes not created—run the setup commands
- Check the correct namespace in Temporal Cloud
No threads returned from search:
- Verify search attributes exist:
temporal operator search-attribute list - Check query syntax in the API request
Codec/Encryption Issues
Web UI shows binary data:
- Codec server not enabled or not reachable
- Configure codec server URL in Web UI settings
- Check CORS origins allow the Web UI domain
- Expected for any workflow-bound (
binary/encrypted-v2) payload: the codec server has no workflow ID to decrypt with (see Codec Server for Temporal Web UI)
Decryption failures:
Error: cipher: message authentication failed
- Wrong password or salt
- Data encrypted with different key
- Verify environment variables match between workers
Cannot read old workflows after password change:
- Workflows encrypted with old password cannot be decrypted
- Never change encryption password without migrating data
- Consider running multiple codec servers during migration
Common Misconfigurations
| Symptom | Likely Cause | Fix |
|---|---|---|
| Workflows route to wrong agent | Same task queue for different agents | Use unique task queues |
| State lost on restart | Using dev server (in-memory) | Use persistent storage |
| Search not working | Search attributes not created | Run setup commands |
| High latency | Temporal server overloaded | Scale Temporal cluster |
| "namespace not found" | Wrong namespace name | Check namespace spelling |
Quick Reference
Minimum Development Setup
# Start Temporal
temporal server start-dev
# Configure AgentVisor
export AGENTVISOR_TEMPORAL_TARGET=localhost:7233
export AGENTVISOR_TEMPORAL_NAMESPACE=default
export AGENTVISOR_TEMPORAL_TASK_QUEUE=my-agent
Minimum Production Setup (Temporal Cloud)
export AGENTVISOR_TEMPORAL_TARGET=my-ns.acct.tmprl.cloud:7233
export AGENTVISOR_TEMPORAL_NAMESPACE=my-ns.acct
export AGENTVISOR_TEMPORAL_TASK_QUEUE=my-agent-prod
export AGENTVISOR_TEMPORAL_AUTH_TYPE=api_key
export AGENTVISOR_TEMPORAL_AUTH_API_KEY=<your-key>
Production with Encryption
export AGENTVISOR_TEMPORAL_TARGET=my-ns.acct.tmprl.cloud:7233
export AGENTVISOR_TEMPORAL_NAMESPACE=my-ns.acct
export AGENTVISOR_TEMPORAL_TASK_QUEUE=my-agent-prod
export AGENTVISOR_TEMPORAL_AUTH_TYPE=api_key
export AGENTVISOR_TEMPORAL_AUTH_API_KEY=<your-key>
export AGENTVISOR_TEMPORAL_CODEC_ENABLED=true
export AGENTVISOR_TEMPORAL_CODEC_TYPE=aes256
export AGENTVISOR_TEMPORAL_CODEC_AES256_PASSWORD=<secure-password>
export AGENTVISOR_TEMPORAL_CODEC_AES256_SALT=<unique-salt>
See Also
- Temporal Integration Concepts — Architecture deep-dive
- External Checkpoint Storage — Raise checkpoint and compaction payload ceilings past Temporal's per-payload limit
- Payload Encryption — Encryption algorithm details
- Scaling and Resilience — High availability configuration
- Production Deployment — Security hardening
- Temporal Documentation — Official Temporal docs
- Temporal Cloud Documentation — Cloud-specific guidance