Skip to main content
The temporal-server validate-dynamic-config command validates dynamic configuration files for syntax errors, unknown keys, and type mismatches.

Synopsis

temporal-server validate-dynamic-config <file> [<file>...]

Description

Validates one or more dynamic configuration YAML files against known configuration keys and their expected types. This command helps catch configuration errors before deploying to production. The validator checks:
  • YAML syntax validity
  • Known configuration keys
  • Correct value types for each key
  • Valid constraint names
  • Proper constraint value types

Arguments

file

Path to one or more dynamic configuration files to validate.
  • Type: String (file path)
  • Required: Yes (at least one file)
  • Multiple: Yes
# Validate single file
temporal-server validate-dynamic-config config/dynamicconfig/development.yaml

# Validate multiple files
temporal-server validate-dynamic-config \
  config/dynamicconfig/development.yaml \
  config/dynamicconfig/production.yaml

Output

For each file, the command prints:
  • File name
  • Any errors found
  • Any warnings found
At the end, it prints a summary with the total error count.

Success Output

$ temporal-server validate-dynamic-config config/dynamicconfig/development.yaml
config/dynamicconfig/development.yaml
No output means the file is valid.

Error Output

$ temporal-server validate-dynamic-config config/dynamicconfig/production.yaml
config/dynamicconfig/production.yaml
  error: unknown key: "frontend.invalidKey"
  error: type mismatch for "history.maxAutoResetPoints": expected int, got string
  warning: key "matching.forwarderMaxRatePerSecond" has no value
3 total errors

Exit Codes

  • 0: All files are valid (no errors)
  • 1: One or more files contain errors

Common Errors

Unknown Key

# Invalid - typo in key name
frontend.namespacRPS:  # Should be "namespaceRPS"
  - value: 1000
Error: unknown key: "frontend.namespacRPS"

Type Mismatch

# Invalid - wrong type
history.maxAutoResetPoints:
  - value: "twenty"  # Should be int
Error: type mismatch for "history.maxAutoResetPoints": expected int, got string

Invalid Constraint

# Invalid - unknown constraint
frontend.namespaceRPS:
  - value: 1000
    constraints:
      invalidConstraint: "value"  # Not a valid constraint name
Error: unknown constraint: "invalidConstraint"

Missing Value

# Invalid - no value provided
frontend.namespaceRPS:
  - constraints:
      namespace: "my-namespace"
Warning: key "frontend.namespaceRPS" has no value

Valid Configuration Example

# Rate limiting
frontend.namespaceRPS:
  - value: 5000
    constraints:
      namespace: "high-throughput"
  - value: 1000  # default

# History limits
history.maxAutoResetPoints:
  - value: 50
    constraints:
      namespace: "long-running"
  - value: 20

history.historyCountLimitError:
  - value: 100000
    constraints:
      namespace: "special-namespace"
  - value: 50000

# Matching configuration
matching.numTaskqueueWritePartitions:
  - value: 16
    constraints:
      namespace: "prod-namespace"
      taskQueueName: "main-queue"
  - value: 4

# Boolean values
system.forceSearchAttributesCacheRefreshOnRead:
  - value: true

# Duration values
matching.longPollExpirationInterval:
  - value: 60s
    constraints:
      namespace: "my-namespace"

Validation in CI/CD

GitHub Actions

name: Validate Config

on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Download Temporal Server
        run: |
          curl -sSf https://temporal.download/cli.sh | sh
          
      - name: Validate Dynamic Config
        run: |
          temporal-server validate-dynamic-config \
            config/dynamicconfig/*.yaml

GitLab CI

validate-config:
  image: temporalio/server:latest
  script:
    - temporal-server validate-dynamic-config config/dynamicconfig/*.yaml
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "main"'

Pre-commit Hook

#!/bin/bash
# .git/hooks/pre-commit

echo "Validating dynamic config..."
temporal-server validate-dynamic-config config/dynamicconfig/*.yaml

if [ $? -ne 0 ]; then
  echo "Dynamic config validation failed. Commit aborted."
  exit 1
fi

Makefile Integration

.PHONY: validate-config
validate-config:
	@echo "Validating dynamic configuration..."
	@temporal-server validate-dynamic-config config/dynamicconfig/*.yaml

.PHONY: validate-all
validate-all: validate-config
	@echo "Running all validations..."
	# Add other validation steps

Best Practices

  1. Validate Before Deploy: Always validate configs before deploying to production
  2. Automate Validation: Add validation to CI/CD pipelines
  3. Version Control: Keep dynamic configs in version control
  4. Comment Changes: Document why specific values were chosen
  5. Test Changes: Test config changes in development first
  6. Regular Review: Periodically review and update configurations

Troubleshooting

File Not Found

$ temporal-server validate-dynamic-config config.yaml
open config.yaml: no such file or directory
Verify the file path is correct and the file exists.

Permission Denied

$ temporal-server validate-dynamic-config /etc/temporal/config.yaml
open /etc/temporal/config.yaml: permission denied
Ensure you have read permissions for the file.

YAML Syntax Error

$ temporal-server validate-dynamic-config config.yaml
config.yaml
  error: yaml: line 5: found unexpected end of stream
Fix YAML syntax errors. Common issues:
  • Missing colons
  • Incorrect indentation
  • Unclosed quotes
  • Invalid characters

Examples

Validate Development Config

temporal-server validate-dynamic-config config/dynamicconfig/development.yaml

Validate All Environment Configs

temporal-server validate-dynamic-config \
  config/dynamicconfig/development.yaml \
  config/dynamicconfig/staging.yaml \
  config/dynamicconfig/production.yaml

Validate with Wildcard

temporal-server validate-dynamic-config config/dynamicconfig/*.yaml

Validate and Show Only Errors

temporal-server validate-dynamic-config config/dynamicconfig/*.yaml 2>&1 | grep -i error

See Also

Build docs developers (and LLMs) love