{"record":{"id":"a50a17b3cf118068","repo":"aeron-io/aeron","slug":"clusterbackup-context-catchupendpoint-must-be-set","errorCode":null,"errorMessage":"ClusterBackup.Context.catchupEndpoint must be set","messagePattern":"ClusterBackup\\.Context\\.catchupEndpoint must be set","errorType":"validation","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ClusterBackup.java","lineNumber":704,"sourceCode":"            }\n\n            if (null == clusterDir)\n            {\n                clusterDir = new File(clusterDirectoryName);\n            }\n            else\n            {\n                clusterDirectoryName = clusterDir.getPath();\n            }\n\n            if (deleteDirOnStart)\n            {\n                IoUtil.delete(clusterDir, false);\n            }\n\n            if (null == catchupEndpoint)\n            {\n                throw new ClusterException(\"ClusterBackup.Context.catchupEndpoint must be set\");\n            }\n\n            if (!clusterDir.exists() && !clusterDir.mkdirs())\n            {\n                throw new ClusterException(\"failed to create cluster dir: \" + clusterDir.getAbsolutePath());\n            }\n\n            if (null == markFileDir)\n            {\n                final String dir = ClusteredServiceContainer.Configuration.markFileDir();\n                markFileDir = Strings.isEmpty(dir) ? clusterDir : new File(dir);\n            }\n\n            if (!markFileDir.exists() && !markFileDir.mkdirs())\n            {\n                throw new ArchiveException(\"failed to create mark file dir: \" + markFileDir.getAbsolutePath());\n            }\n","sourceCodeStart":686,"sourceCodeEnd":722,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ClusterBackup.java#L686-L722","documentation":"During ClusterBackup.Context.conclude(), the catchupEndpoint property is mandatory — the backup client must know where to request a catchup replay from the cluster. If it was never set via catchupEndpoint(...), conclude() throws this ClusterException before starting anything.","triggerScenarios":"Building a ClusterBackup Context without calling ClusterBackup.Context.catchupEndpoint(String) and then concluding/starting the ClusterBackup.","commonSituations":"New users of the cluster backup API omitting the required endpoint (e.g. 'localhost:9010' style host:port of a cluster member); migrating from older Aeron versions where it defaulted from other configuration.","solutions":["Call catchupEndpoint(\"host:port\") on the ClusterBackup.Context before conclude(), pointing at a cluster member's catchup listener.","Set the equivalent system property / configuration value (aeron.cluster.backup.catchup.endpoint) if using property-based configuration.","Verify the endpoint matches one actually bound by the cluster member's backup/catchup server."],"exampleFix":"// before\nClusterBackup.Context ctx = new ClusterBackup.Context(); // no catchupEndpoint\n// after\nClusterBackup.Context ctx = new ClusterBackup.Context()\n    .catchupEndpoint(\"localhost:9010\");","handlingStrategy":"validation","validationCode":"if (ctx instanceof ClusterBackup.Context c && c.catchupEndpoint() == null) { throw new IllegalArgumentException(\"catchupEndpoint required\"); }","typeGuard":"static boolean catchupEndpointSet(ClusterBackup.Context ctx) { return ctx.catchupEndpoint() != null; }","tryCatchPattern":"try {\n    ctx.conclude();\n} catch (ClusterException e) {\n    if (e.getMessage().contains(\"catchupEndpoint\")) { log.error(\"set ClusterBackup.Context.catchupEndpoint before conclude\"); }\n    throw e;\n}","preventionTips":["Always call catchupEndpoint(...) in a shared factory that builds the backup Context","Point the endpoint at a verified cluster member catchup listener","Add a startup smoke test that concludes the backup context"],"tags":["configuration","required-field","cluster-backup","aeron-cluster"],"backgroundTag":"missing-required-config-field","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}