{"record":{"id":"5688b9c925146013","repo":"aeron-io/aeron","slug":"clustermembers-and-endpoints-differ-member-endpoints","errorCode":null,"errorMessage":"clusterMembers and endpoints differ: ${member.endpoints} != ${memberEndpoints}","messagePattern":"clusterMembers and endpoints differ: (.+?) != (.+?)","errorType":"validation","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ClusterMember.java","lineNumber":1085,"sourceCode":"\n        return member;\n    }\n\n    /**\n     * Check the member with the memberEndpoints.\n     *\n     * @param member          to check memberEndpoints against.\n     * @param memberEndpoints to check member against.\n     * @see ConsensusModule.Context#memberEndpoints()\n     * @see ConsensusModule.Context#clusterMembers()\n     */\n    public static void validateMemberEndpoints(final ClusterMember member, final String memberEndpoints)\n    {\n        final ClusterMember endpoints = ClusterMember.parseEndpoints(NULL_VALUE, memberEndpoints);\n\n        if (!areSameEndpoints(member, endpoints))\n        {\n            throw new ClusterException(\n                \"clusterMembers and endpoints differ: \" + member.endpoints + \" != \" + memberEndpoints);\n        }\n    }\n\n    /**\n     * Are two cluster members using the same endpoints?\n     *\n     * @param lhs to compare for equality.\n     * @param rhs to compare for equality.\n     * @return true if both are using the same endpoints or false if not.\n     */\n    public static boolean areSameEndpoints(final ClusterMember lhs, final ClusterMember rhs)\n    {\n        return lhs.ingressEndpoint.equals(rhs.ingressEndpoint) &&\n            lhs.consensusEndpoint.equals(rhs.consensusEndpoint) &&\n            lhs.logEndpoint.equals(rhs.logEndpoint) &&\n            lhs.catchupEndpoint.equals(rhs.catchupEndpoint) &&\n            lhs.archiveEndpoint.equals(rhs.archiveEndpoint);","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ClusterMember.java#L1067-L1103","documentation":"ClusterMember.validateMemberEndpoints compares the endpoints parsed from a member's entry in the clusterMembers config string against the memberEndpoints string supplied for that member. If they differ, it throws ClusterException. This guards against a member whose configured membership list and its own advertised endpoints disagree, which would break cluster connectivity.","triggerScenarios":"Calling ClusterMember.validateMemberEndpoints(member, memberEndpoints) where member.endpoints (parsed from the clusterMembers string) does not exactly equal the parsed memberEndpoints string for that member (mismatched client-facing, member-facing, log, archive or replication endpoints).","commonSituations":"Startup validation of a cluster member where the clusterMembers system property and the member's own aeron.cluster.member.endpoints were edited independently; a copy-paste error leaving an old port or hostname in one of the two; automated config generation producing inconsistent values.","solutions":["Compare the member's entry in the clusterMembers list with aeron.cluster.member.endpoints and make them byte-for-byte identical (same endpoints in same order).","Check for stale ports/hostnames after a migration and update both properties together.","If generated by a tool, fix the generator so both values come from a single source of truth.","Restart the node after correcting the configuration."],"exampleFix":"// before\n-Daeron.cluster.members=0,hostA:20000,hostA:20001,hostA:20002,hostA:20003,hostA:20004|1,hostB:20000,...\n-Daeron.cluster.member.endpoints=hostA:20000,hostA:20001,hostA:20003,hostA:20004\n// after (member-level endpoints must match the clusterMembers entry exactly)\n-Daeron.cluster.member.endpoints=hostA:20000,hostA:20001,hostA:20002,hostA:20003,hostA:20004","handlingStrategy":"validation","validationCode":"// before starting the node\nClusterMember[] members = ClusterMember.parse(0, memberEndpointsConfigString);\nClusterMember thisMember = ClusterMember.findMember(members, ClusterMember.parse(NULL_VALUE, memberEndpoints));\nif (thisMember == null) {\n    throw new IllegalArgumentException(\"member endpoints not found in clusterMembers list\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate clusterMembers and aeron.cluster.member.endpoints from a single config source.","Diff both endpoint strings after every config change.","Validate endpoint parity in a startup script before launching the node."],"tags":["aeron","cluster","configuration","endpoints"],"backgroundTag":"invalid-config-value","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}