{"record":{"id":"001e5d22aeb2c797","repo":"aeron-io/aeron","slug":"aeron-spies-are-invalid-as-send-destinations-channel","errorCode":null,"errorMessage":"Aeron spies are invalid as send destinations: channel={destinationUri}","messagePattern":"Aeron spies are invalid as send destinations: channel=(.+?)","errorType":"validation","errorClass":"InvalidChannelException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java","lineNumber":2375,"sourceCode":"                udpChannel.originalUriString());\n        }\n    }\n\n    private static void validateTimestampConfiguration(final UdpChannel udpChannel)\n    {\n        if (null != udpChannel.channelUri().get(MEDIA_RCV_TIMESTAMP_OFFSET_PARAM_NAME))\n        {\n            throw new InvalidChannelException(\n                \"Media timestamps '\" + MEDIA_RCV_TIMESTAMP_OFFSET_PARAM_NAME +\n                    \"' are not supported in the Java driver: channel=\" + udpChannel.originalUriString());\n        }\n    }\n\n    private static void validateDestinationUri(final ChannelUri uri, final String destinationUri)\n    {\n        if (SPY_QUALIFIER.equals(uri.prefix()))\n        {\n            throw new InvalidChannelException(\"Aeron spies are invalid as send destinations: channel=\" +\n                destinationUri);\n        }\n\n        for (final String invalidKey : INVALID_DESTINATION_KEYS)\n        {\n            if (uri.containsKey(invalidKey))\n            {\n                throw new InvalidChannelException(\n                    \"destinations must not contain the key: \" + invalidKey + \" channel=\" + destinationUri);\n            }\n        }\n\n        if (Objects.equals(CONTROL_MODE_RESPONSE, uri.get(MDC_CONTROL_MODE_PARAM_NAME)))\n        {\n            throw new InvalidChannelException(\"destinations may not specify \" +\n                MDC_CONTROL_MODE_PARAM_NAME + \"=\" + CONTROL_MODE_RESPONSE);\n        }\n    }","sourceCodeStart":2357,"sourceCodeEnd":2393,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java#L2357-L2393","documentation":"An Aeron \"spy\" channel (URI prefixed with \"aeron-spy:\") is a virtual channel that taps traffic from an existing network publication via local shared memory. Spies can only be used for subscriptions; using one as a send/publication destination is invalid and rejected with InvalidChannelException.","triggerScenarios":"Adding a spy URI as a publication or send destination, e.g. ChannelUri with prefix \"aeron-spy:\" passed to addPublication(), addDestination(), or MDC manual destination lists.","commonSituations":"Confusing spy subscriptions with spy publications; building dynamic destination lists where a spy URI sneaks in; misunderstanding that spy is receive-only local tapping.","solutions":["Use a plain \"aeron:udp?...\" URI for send destinations instead of a spy prefix.","Only use aeron-spy URIs with addSubscription() to locally tap an existing publication.","Validate destination URIs in your code, rejecting any prefix other than \"aeron:\" for sends."],"exampleFix":"// before\npublication.addDestination(\"aeron-spy:udp?endpoint=localhost:40456\");\n// after\npublication.addDestination(\"aeron:udp?endpoint=localhost:40456\");","handlingStrategy":"validation","validationCode":"ChannelUri uri = ChannelUri.parse(destination);\nif (\"aeron-spy\".equals(uri.prefix())) throw new IllegalArgumentException(\"spy cannot be a send destination\");","typeGuard":"boolean isSendableDestination(ChannelUri uri) {\n  return !\"aeron-spy\".equals(uri.prefix());\n}","tryCatchPattern":"try { publication.addDestination(destination); }\ncatch (InvalidChannelException e) { if (e.getMessage().contains(\"spies are invalid as send destinations\")) { /* replace with aeron:udp URI */ } else throw e; }","preventionTips":["Restrict aeron-spy prefixes to subscription code paths","Filter destination lists to \"aeron:\" prefixes before adding","Document spy semantics as receive-only in team guidelines"],"tags":["aeron","spy-channel","destination","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}