private void returnErrorToSender(@Nonnull final Packet packet) {
            XMPPServer server = XMPPServer.getInstance();
            JID from = packet.getFrom();
            JID to = packet.getTo();
            if (!server.isLocal(from) && !XMPPServer.getInstance().matchesComponent(from) &&
                    !server.isLocal(to) && !XMPPServer.getInstance().matchesComponent(to)) {
                // Do nothing since the sender and receiver of the packet that failed to reach a remote
                // server are not local users. This prevents endless loops if the FROM or TO address
                // are non-existent addresses
                return;
            }

            final Set<Packet> replies = new HashSet<>();

            // TODO Send correct error condition: timeout or not_found depending on the real error
            try {
                if (packet instanceof IQ) {
                    if (((IQ) packet).isRequest()) {
                        IQ reply = new IQ();
                        reply.setID(packet.getID());
                        reply.setTo(from);
                        reply.setFrom(to);
                        reply.setChildElement(((IQ) packet).getChildElement().createCopy());
                        reply.setError(PacketError.Condition.remote_server_not_found);
                        replies.add( reply );
                    }
                }
                else if (packet instanceof Presence) {
                    // workaround for OF-23. "undo" the 'setFrom' to a bare JID 
                    // by sending the error to all available resources.
                    final List<JID> routes = new ArrayList<>();
                    if (from.getResource() == null || from.getResource().trim().isEmpty()) {
                        routes.addAll(routingTable.getRoutes(from, null));
                    } else {
                        routes.add(from);
                    }
                    
                    for (JID route : routes) {
                        Presence reply = new Presence();
                        reply.setID(packet.getID());
                        reply.setTo(route);
                        reply.setFrom(to);
                        reply.setError(PacketError.Condition.remote_server_not_found);

                        replies.add( reply );
                    }
                }
                else if (packet instanceof Message) {
                    Message reply = new Message();
                    reply.setID(packet.getID());
                    reply.setTo(from);
                    reply.setFrom(to);
                    reply.setType(((Message)packet).getType());
                    reply.setThread(((Message)packet).getThread());
                    reply.setError(PacketError.Condition.remote_server_not_found);

                    replies.add( reply );
                }
            }
            catch (Exception e)
            {
                Log.warn( "An exception occurred while trying to generate a remote-server-not-found error (for domain '{}') to the original sender. Original packet: {}", domainPair.getRemote(), packet, e );
            }

            // Send all replies.
            for ( final Packet reply : replies )
            {
                TaskEngine.getInstance().submit(() -> {
                    try
                    {
                        XMPPServer.getInstance().getPacketRouter().route( reply );
                    }
                    catch (Exception e)
                    {
                        Log.warn( "An exception occurred while trying to returning a remote-server-not-found error (for domain '{}') to the original sender. Original packet: {}", domainPair.getRemote(), packet, e );
                    }
                });
            }
        }
Processes stanzas that could not be delivered to a remote domain, by generating error responses where
appropriate.

@param packet The stanza that could not be delivered.
xmppserver/src/main/java/org/jivesoftware/openfire/server/OutgoingSessionPromise.java