{"record":{"id":"0e8811517d563a1c","repo":"temporalio/temporal","slug":"uri-is-invalid","errorCode":null,"errorMessage":"URI is invalid","messagePattern":"URI is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/archiver/constants.go","lineNumber":27,"sourceCode":"\tArchiveNonRetryableErrorMsg = \"Archive method encountered an non-retryable error.\"\n\t// ArchiveTransientErrorMsg is the log message when the Archive() method encounters a transient error\n\tArchiveTransientErrorMsg = \"Archive method encountered a transient error.\"\n\t// ArchiveSkippedInfoMsg is the log messsage when the Archive() method encounter an not found error\n\tArchiveSkippedInfoMsg = \"Archive method encountered not found error and skipped the archival\"\n\n\t// ErrReasonInvalidURI is the error reason for invalid URI\n\tErrReasonInvalidURI = \"URI is invalid\"\n\t// ErrReasonInvalidArchiveRequest is the error reason for invalid archive request\n\tErrReasonInvalidArchiveRequest = \"archive request is invalid\"\n\t// ErrReasonReadHistory is the error reason for failing to read history\n\tErrReasonReadHistory = \"failed to read history batches\"\n\t// ErrReasonHistoryMutated is the error reason for mutated history\n\tErrReasonHistoryMutated = \"history was mutated\"\n)\n\nvar (\n\t// ErrInvalidURI is the error for invalid URI\n\tErrInvalidURI = errors.New(\"URI is invalid\")\n\t// ErrURISchemeMismatch is the error for mismatch between URI scheme and archiver\n\tErrURISchemeMismatch = errors.New(\"URI scheme does not match the archiver\")\n\t// ErrHistoryMutated is the error for mutated history\n\tErrHistoryMutated = errors.New(\"history was mutated\")\n\t// ErrInvalidGetHistoryRequest is the error for invalid GetHistory request\n\tErrInvalidGetHistoryRequest = errors.New(\"get archived history request is invalid\")\n\t// ErrInvalidQueryVisibilityRequest is the error for invalid Query Visibility request\n\tErrInvalidQueryVisibilityRequest = errors.New(\"query visiblity request is invalid\")\n\t// ErrNextPageTokenCorrupted is the error for corrupted GetHistory token\n\tErrNextPageTokenCorrupted = errors.New(\"next page token is corrupted\")\n\t// ErrHistoryNotExist is the error for non-exist history\n\tErrHistoryNotExist = errors.New(\"requested workflow history does not exist\")\n)\n","sourceCodeStart":9,"sourceCodeEnd":41,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/archiver/constants.go#L9-L41","documentation":"validateServerTLS checks mutual exclusivity of inline vs file-based TLS material. ServerTLS allows supplying the private key either as a file path (KeyFile) or as inline PEM data (KeyData), but not both at once, because the loader would be ambiguous about which source to trust. This error is returned when both fields are non-empty.","triggerScenarios":"Calling validateGroupTLS/validateServerTLS with a config.ServerTLS where both KeyFile and KeyData are set to non-empty values.","commonSituations":"Merging TLS config from multiple sources (e.g. a base YAML plus dynamicconfig overrides) so both a key path and pasted PEM data end up set; copying an example config and filling in both fields; secret-management tooling injecting KeyData while KeyFile is already in the config file.","solutions":["Remove KeyFile from the ServerTLS config and keep only KeyData (or vice versa).","If config comes from multiple layers, ensure only one layer supplies the key and the other leaves the field empty.","If KeyData is injected by a secret manager, set KeyFile: \"\" explicitly in the base config.","Add a config lint/startup check that fails fast on both fields being set with a clearer operator-facing message."],"exampleFix":"// before\nServerTLS:\n  KeyFile: /etc/temporal/tls.key\n  KeyData: |\n    -----BEGIN PRIVATE KEY-----\n// after\nServerTLS:\n  KeyData: |\n    -----BEGIN PRIVATE KEY-----","handlingStrategy":"validation","validationCode":"func validateKeyExclusivity(cfg *config.ServerTLS) error {\n\tif cfg.KeyFile != \"\" && cfg.KeyData != \"\" {\n\t\treturn fmt.Errorf(\"set only one of ServerTLS.KeyFile or ServerTLS.KeyData\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In config templates, keep KeyFile empty wherever KeyData is populated.","When merging config layers, assert exactly one TLS key source survives the merge.","Write a CI check that parses the server TLS config and enforces File/Data mutual exclusivity for all fields."],"tags":["tls","config-validation","mutually-exclusive-fields"],"backgroundTag":"tls-config-conflict","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}