temporalio/temporal · error
invalid operation token
Error message
invalid operation token
What it means
validateCAs iterates a list of CA entries (inline PEM data or file paths) and rejects any entry whose TrimSpace is empty. This is a guard against silently building an empty or malformed CA pool from blank list items, which would cause hard-to-debug TLS verification failures later.
Source
Thrown at chasm/lib/nexusoperation/task_handler_helpers.go:28
"time"
"github.com/nexus-rpc/sdk-go/nexus"
commonpb "go.temporal.io/api/common/v1"
enumspb "go.temporal.io/api/enums/v1"
failurepb "go.temporal.io/api/failure/v1"
"go.temporal.io/api/serviceerror"
persistencespb "go.temporal.io/server/api/persistence/v1"
tokenspb "go.temporal.io/server/api/token/v1"
"go.temporal.io/server/common"
"go.temporal.io/server/common/namespace"
commonnexus "go.temporal.io/server/common/nexus"
"go.temporal.io/server/common/nexus/nexusrpc"
queueserrors "go.temporal.io/server/service/history/queues/errors"
)
var (
ErrResponseBodyTooLarge = errors.New("http: response body too large")
ErrInvalidOperationToken = errors.New("invalid operation token")
errRequestTimedOut = errors.New("request timed out")
errOpProcessorFailed = errors.New("nexus operation processor failed")
)
const maxDuration = time.Duration(1<<63 - 1)
type operationTimeoutBelowMinError struct {
timeoutType enumspb.TimeoutType
}
func (o *operationTimeoutBelowMinError) Error() string {
return fmt.Sprintf("not enough time to execute another request before %s timeout", o.timeoutType.String())
}
func isDestinationDown(err error) bool {
if _, ok := errors.AsType[serviceerror.ServiceError](err); ok {
return false
}View on GitHub (pinned to bde624efd1)
Solutions
- Delete the empty entry from the CA list in your config.
- Fix whatever produced the blank value (unset env var, missing secret, bad template).
- If a CA is optional, omit the entry entirely instead of passing "".
- Pre-validate the rendered config with a script that trims and drops blank CA entries before startup.
Example fix
// before RootCAData: ["-----BEGIN CERTIFICATE-----...", " "] // after RootCAData: ["-----BEGIN CERTIFICATE-----..."]
Defensive patterns
Strategy: validation
Validate before calling
func hasEmptyCA(cas []string) bool {
for _, ca := range cas {
if strings.TrimSpace(ca) == "" {
return true
}
}
return false
} Prevention
- Sanitize CA lists (trim/drop blanks) right after config load, before validation.
- Treat empty CA entries as config corruption, not an optional value.
- Test config rendering in CI with the same templates used in production.
When it happens
Trigger: Any validateServerTLS or validateClientTLS path where ClientCAData/ClientCAFiles/RootCAData/RootCAFiles contains "" or a whitespace-only string.
Common situations: Empty YAML list items, env-var substitution expanding to nothing, unfilled template placeholders, secret mount not present so data is blank, copy-paste trailing empty element.
Related errors
- URI scheme does not match the archiver
- history was mutated
- query visiblity request is invalid
- next page token is corrupted
- URI is invalid
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/b19199c2de2e1c1a.
Report an issue: GitHub.