{"record":{"id":"b6ac3ae0e3da11df","repo":"apache/beam","slug":"unknown-or-unsupported-time-domain-s","errorCode":null,"errorMessage":"Unknown or unsupported time domain %s","messagePattern":"Unknown or unsupported time domain (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java","lineNumber":1345,"sourceCode":"      this.timerIdOrFamily = timerIdOrFamily;\n      this.userKey = userKey;\n      this.dynamicTimerTag = dynamicTimerTag;\n      this.elementTimestampOrTimerHoldTimestamp = elementTimestampOrTimerHoldTimestamp;\n      this.boundedWindow = boundedWindow;\n      this.paneInfo = paneInfo;\n      this.noOutputTimestamp = false;\n      this.timeDomain = timeDomain;\n\n      switch (timeDomain) {\n        case EVENT_TIME:\n          fireTimestamp = elementTimestampOrTimerFireTimestamp;\n          break;\n        case PROCESSING_TIME:\n          // TODO: This should use an injected clock when using TestStream.\n          fireTimestamp = new Instant(DateTimeUtils.currentTimeMillis());\n          break;\n        default:\n          throw new IllegalArgumentException(\n              String.format(\"Unknown or unsupported time domain %s\", timeDomain));\n      }\n    }\n\n    @Override\n    public void set(Instant absoluteTime) {\n      checkNotNull(timerBundleTracker);\n      // Ensures that the target time is reasonable. For event time timers this means that the time\n      // should be prior to window GC time.\n      if (TimeDomain.EVENT_TIME.equals(timeDomain)) {\n        Instant windowExpiry = LateDataUtils.garbageCollectionTime(currentWindow, allowedLateness);\n        checkArgument(\n            !absoluteTime.isAfter(windowExpiry),\n            \"Attempted to set event time timer for %s but that is after\"\n                + \" the expiration of window %s\",\n            absoluteTime,\n            windowExpiry);\n      }","sourceCodeStart":1327,"sourceCodeEnd":1363,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java#L1327-L1363","documentation":"Thrown by FnApiDoFnRunner when handling a timer firing whose time domain is not one of the supported domains (EVENT_TIME, PROCESSING_TIME). The Java Fn API harness only implements timer callbacks for these domains, so any other domain value reaching the switch's default branch is rejected with an IllegalArgumentException.","triggerScenarios":"A timer registered or delivered via the Beam Fn API with a timeDomain other than EVENT_TIME or PROCESSING_TIME reaches the runner's timer-firing dispatch switch (default case at FnApiDoFnRunner.java:1345).","commonSituations":"A runner or SDK adds a new time domain (e.g. WATERMARK/synchronized processing time variants) while the Java Fn API harness has not been updated to handle it; cross-language pipelines where one SDK emits a timer domain the Java harness doesn't know; a wire/protocol mismatch between older and newer Beam versions.","solutions":["Check which time domain the DoFn/Timer was registered with and use only EVENT_TIME or PROCESSING_TIME.","Align Beam SDK versions on both runner and SDK sides so the timer domain enum is understood consistently.","If you control the runner side, add a case for the new domain in FnApiDoFnRunner's switch instead of falling through to default.","Inspect the serialized timer payload sent over the Fn API to confirm the timeDomain field isn't corrupted or mis-encoded."],"exampleFix":"// before (DoFn using an unsupported domain path)\nTimer.timer(domain);\n\n// after: only use supported domains\nTimer.eventTime(\"myTimer\"); // or Timer.processingTime(\"myTimer\")","handlingStrategy":"try-catch","validationCode":"if (!timeDomain.equals(TimeDomain.EVENT_TIME) && !timeDomain.equals(TimeDomain.PROCESSING_TIME)) {\n  throw new IllegalArgumentException(\"Unsupported time domain: \" + timeDomain);\n}","typeGuard":"boolean isSupported(TimeDomain d) { return d == TimeDomain.EVENT_TIME || d == TimeDomain.PROCESSING_TIME; }","tryCatchPattern":"try {\n  emitTimerCallback(timeDomain);\n} catch (IllegalArgumentException e) {\n  logger.error(\"Timer domain rejected: {}\", timeDomain, e);\n}","preventionTips":["Only register EVENT_TIME or PROCESSING_TIME timers in DoFns","Keep runner and SDK Beam versions aligned","Add a unit test covering every time domain your timers use"],"tags":["beam","timer","time-domain","illegal-argument"],"backgroundTag":"unsupported-enum-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}