diff --git a/src/App.php b/src/App.php
index 25770dd782..0d4e8880dd 100644
--- a/src/App.php
+++ b/src/App.php
@@ -631,10 +631,10 @@ class App
 
 			// ZRL
 			if (!empty($_GET['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) {
-				// Only continue when the given profile link seems valid
+				// Only continue when the given profile link seems valid.
 				// Valid profile links contain a path with "/profile/" and no query parameters
 				if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == '') &&
-					strstr(parse_url($_GET['zrl'], PHP_URL_PATH), '/profile/')) {
+					strpos(parse_url($_GET['zrl'], PHP_URL_PATH) ?? '', '/profile/') !== false) {
 					if ($this->session->get('visitor_home') != $_GET['zrl']) {
 						$this->session->set('my_url', $_GET['zrl']);
 						$this->session->set('authenticated', 0);
diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php
index 0cfc8df345..711a8549f2 100644
--- a/src/Contact/Avatar.php
+++ b/src/Contact/Avatar.php
@@ -125,7 +125,7 @@ class Avatar
 
 	private static function getFilename(string $url): string
 	{
-		$guid = Item::guidFromUri($url, parse_url($url, PHP_URL_HOST));
+		$guid = Item::guidFromUri($url);
 
 		return substr($guid, 0, 2) . '/' . substr($guid, 3, 2) . '/' . substr($guid, 5, 3) . '/' .
 			substr($guid, 9, 2) .'/' . substr($guid, 11, 2) . '/' . substr($guid, 13, 4). '/' . substr($guid, 18) . '-';
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index ae21d05e13..62ad04a434 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -273,8 +273,8 @@ class BBCode
 		// Get all linked images with alternative image description
 		if (preg_match_all("/\[img=(http[^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
 			foreach ($pictures as $picture) {
-				if (Photo::isLocal($picture[1])) {
-					$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2]];
+				if ($id = Photo::getIdForName($picture[1])) {
+					$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => $picture[2], 'id' => $id];
 				} else {
 					$post['remote_images'][] = ['url' => $picture[1], 'description' => $picture[2]];
 				}
@@ -286,8 +286,8 @@ class BBCode
 
 		if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
 			foreach ($pictures as $picture) {
-				if (Photo::isLocal($picture[1])) {
-					$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => ''];
+				if ($id = Photo::getIdForName($picture[1])) {
+					$post['images'][] = ['url' => str_replace('-1.', '-0.', $picture[1]), 'description' => '', 'id' => $id];
 				} else {
 					$post['remote_images'][] = ['url' => $picture[1], 'description' => ''];
 				}
diff --git a/src/Model/APContact.php b/src/Model/APContact.php
index 67ce2b66bf..fd748f1cd4 100644
--- a/src/Model/APContact.php
+++ b/src/Model/APContact.php
@@ -291,14 +291,11 @@ class APContact
 			return $fetched_contact;
 		}
 
-		$parts = parse_url($apcontact['url']);
-		unset($parts['scheme']);
-		unset($parts['path']);
-
 		if (empty($apcontact['addr'])) {
-			if (!empty($apcontact['nick']) && is_array($parts)) {
-				$apcontact['addr'] = $apcontact['nick'] . '@' . str_replace('//', '', Network::unparseURL($parts));
-			} else {
+			try {
+				$apcontact['addr'] = $apcontact['nick'] . '@' . (new Uri($apcontact['url']))->getAuthority();
+			} catch (\Throwable $e) {
+				Logger::warning('Unable to coerce APContact URL into a UriInterface object', ['url' => $apcontact['url'], 'error' => $e->getMessage()]);
 				$apcontact['addr'] = '';
 			}
 		}
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index e80f0752ea..c20435278f 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -1395,7 +1395,17 @@ class Contact
 		}
 
 		if ($data['network'] == Protocol::DIASPORA) {
-			DI::dsprContact()->updateFromProbeArray($data);
+			try {
+				DI::dsprContact()->updateFromProbeArray($data);
+			} catch (\InvalidArgumentException $e) {
+				Logger::error($e->getMessage(), ['url' => $url, 'data' => $data]);
+			}
+		} elseif (!empty($data['networks'][Protocol::DIASPORA])) {
+			try {
+				DI::dsprContact()->updateFromProbeArray($data['networks'][Protocol::DIASPORA]);
+			} catch (\InvalidArgumentException $e) {
+				Logger::error($e->getMessage(), ['url' => $url, 'data' => $data['networks'][Protocol::DIASPORA]]);
+			}
 		}
 
 		self::updateFromProbeArray($contact_id, $data);
@@ -2097,7 +2107,7 @@ class Contact
 		if ($static) {
 			$query_params['static'] = true;
 		}
-		
+
 		return $url . ($guid ?: $cid) . (!empty($query_params) ? '?' . http_build_query($query_params) : '');
 	}
 
@@ -2483,13 +2493,23 @@ class Contact
 			return false;
 		}
 
-		$ret = Probe::uri($contact['url'], $network, $contact['uid']);
+		$data = Probe::uri($contact['url'], $network, $contact['uid']);
 
-		if ($ret['network'] == Protocol::DIASPORA) {
-			DI::dsprContact()->updateFromProbeArray($ret);
+		if ($data['network'] == Protocol::DIASPORA) {
+			try {
+				DI::dsprContact()->updateFromProbeArray($data);
+			} catch (\InvalidArgumentException $e) {
+				Logger::error($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]);
+			}
+		} elseif (!empty($data['networks'][Protocol::DIASPORA])) {
+			try {
+				DI::dsprContact()->updateFromProbeArray($data['networks'][Protocol::DIASPORA]);
+			} catch (\InvalidArgumentException $e) {
+				Logger::error($e->getMessage(), ['id' => $id, 'network' => $network, 'contact' => $contact, 'data' => $data]);
+			}
 		}
 
-		return self::updateFromProbeArray($id, $ret);
+		return self::updateFromProbeArray($id, $data);
 	}
 
 	/**
@@ -2671,7 +2691,7 @@ class Contact
 		}
 
 		$update = false;
-		$guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url'], parse_url($ret['url'], PHP_URL_HOST));
+		$guid = ($ret['guid'] ?? '') ?: Item::guidFromUri($ret['url']);
 
 		// make sure to not overwrite existing values with blank entries except some technical fields
 		$keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl'];
@@ -3189,8 +3209,9 @@ class Contact
 		self::clearFollowerFollowingEndpointCache($contact['uid']);
 
 		$cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
-
-		DI::notification()->deleteForUserByVerb($contact['uid'], Activity::FOLLOW, ['actor-id' => $cdata['public']]);
+		if (!empty($cdata['public'])) {
+			DI::notification()->deleteForUserByVerb($contact['uid'], Activity::FOLLOW, ['actor-id' => $cdata['public']]);
+		}
 	}
 
 	/**
diff --git a/src/Model/Item.php b/src/Model/Item.php
index ab8ae337ca..5f7c64a13a 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -2036,9 +2036,10 @@ class Item
 	 * Posts that are created on this system are using System::createUUID.
 	 * Received ActivityPub posts are using Processor::getGUIDByURL.
 	 *
-	 * @param string      $uri uri of an item entry
+	 * @param string      $uri  uri of an item entry
 	 * @param string|null $host hostname for the GUID prefix
 	 * @return string Unique guid
+	 * @throws \Exception
 	 */
 	public static function guidFromUri(string $uri, string $host = null): string
 	{
@@ -2049,11 +2050,16 @@ class Item
 		// Remove the scheme to make sure that "https" and "http" doesn't make a difference
 		unset($parsed['scheme']);
 
+		$hostPart = $host ?? $parsed['host'] ?? '';
+		if (!$hostPart) {
+			Logger::warning('Empty host GUID part', ['uri' => $uri, 'host' => $host, 'parsed' => $parsed, 'callstack' => System::callstack(10)]);
+		}
+
 		// Glue it together to be able to make a hash from it
 		$host_id = implode('/', $parsed);
 
 		// Use a mixture of several hashes to provide some GUID like experience
-		return hash('crc32', $host) . '-'. hash('joaat', $host_id) . '-'. hash('fnv164', $host_id);
+		return hash('crc32', $hostPart) . '-' . hash('joaat', $host_id) . '-' . hash('fnv164', $host_id);
 	}
 
 	/**
diff --git a/src/Model/Mail.php b/src/Model/Mail.php
index 6ccce24ba7..9469483d9a 100644
--- a/src/Model/Mail.php
+++ b/src/Model/Mail.php
@@ -59,8 +59,7 @@ class Mail
 		}
 
 		if (empty($msg['guid'])) {
-			$host = parse_url($msg['from-url'], PHP_URL_HOST);
-			$msg['guid'] = Item::guidFromUri($msg['uri'], $host);
+			$msg['guid'] = Item::guidFromUri($msg['uri'], parse_url($msg['from-url'], PHP_URL_HOST));
 		}
 
 		$msg['created'] = (!empty($msg['created']) ? DateTimeFormat::utc($msg['created']) : DateTimeFormat::utcNow());
diff --git a/src/Module/DFRN/Notify.php b/src/Module/DFRN/Notify.php
index 34cf21f11d..14b121e810 100644
--- a/src/Module/DFRN/Notify.php
+++ b/src/Module/DFRN/Notify.php
@@ -70,18 +70,8 @@ class Notify extends BaseModule
 				throw new \Friendica\Network\HTTPException\InternalServerErrorException();
 			}
 			$this->dispatchPrivate($user, $postdata);
-		} elseif (!$this->dispatchPublic($postdata)) {
-			(new Salmon(
-				$this->database,
-				$this->l10n,
-				$this->baseUrl,
-				$this->args,
-				$this->logger,
-				$this->profiler,
-				$this->response,
-				$this->server,
-				$this->parameters
-			))->rawContent($request);
+		} else {
+			$this->dispatchPublic($postdata);
 		}
 	}
 
diff --git a/src/Module/NoScrape.php b/src/Module/NoScrape.php
index 8e5850ac0b..56f31f2dcf 100644
--- a/src/Module/NoScrape.php
+++ b/src/Module/NoScrape.php
@@ -94,7 +94,7 @@ class NoScrape extends BaseModule
 
 		// We display the last activity (post or login), reduced to year and week number
 		$last_active = strtotime($owner['last-item']);
-		if ($last_active < strtotime($owner['last-activity'])) {
+		if ($owner['last-activity'] && $last_active < strtotime($owner['last-activity'])) {
 			$last_active = strtotime($owner['last-activity']);
 		}
 		$json_info['last-activity'] = date('o-W', $last_active);
diff --git a/src/Module/Notifications/Ping.php b/src/Module/Notifications/Ping.php
index 76cdd9f770..df75c047af 100644
--- a/src/Module/Notifications/Ping.php
+++ b/src/Module/Notifications/Ping.php
@@ -48,6 +48,7 @@ use Friendica\Navigation\Notifications\Factory;
 use Friendica\Navigation\Notifications\Repository;
 use Friendica\Navigation\Notifications\ValueObject;
 use Friendica\Navigation\SystemMessages;
+use Friendica\Network\HTTPException;
 use Friendica\Protocol\Activity;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Profiler;
@@ -229,7 +230,11 @@ class Ping extends BaseModule
 
 			// merge all notification types in one array
 			foreach ($intros as $intro) {
-				$navNotifications[] = $this->formattedNavNotification->createFromIntro($intro);
+				try {
+					$navNotifications[] = $this->formattedNavNotification->createFromIntro($intro);
+				} catch (HTTPException\NotFoundException $e) {
+					$this->introductionRepo->delete($intro);
+				}
 			}
 
 			if (count($registrations) <= 1 || $this->pconfig->get($this->session->getLocalUserId(), 'system', 'detailed_notif')) {
@@ -242,7 +247,7 @@ class Ping extends BaseModule
 						new Uri($this->baseUrl->get(true) . '/moderation/users/pending')
 					);
 				}
-			} elseif (count($registrations) > 1) {
+			} else {
 				$navNotifications[] = $this->formattedNavNotification->createFromParams(
 					$registrations[0]['name'],
 					$registrations[0]['url'],
diff --git a/src/Module/OStatus/Salmon.php b/src/Module/OStatus/Salmon.php
index 0d393afcce..f928e308d5 100644
--- a/src/Module/OStatus/Salmon.php
+++ b/src/Module/OStatus/Salmon.php
@@ -66,11 +66,12 @@ class Salmon extends \Friendica\BaseModule
 	{
 		$xml = Network::postdata();
 
-		$this->logger->debug('New Salmon', ['nickname' => $this->parameters['nickname'], 'xml' => $xml]);
-
-		// Despite having a route with a mandatory nickname parameter, this method can also be called from
-		// \Friendica\Module\DFRN\Notify->post where the same parameter is optional 🤷‍
 		$nickname = $this->parameters['nickname'] ?? '';
+		if (empty($nickname)) {
+			throw new HTTPException\BadRequestException('nickname parameter is mandatory');
+		}
+
+		$this->logger->debug('New Salmon', ['nickname' => $nickname, 'xml' => $xml]);
 
 		$importer = $this->database->selectFirst('user', [], ['nickname' => $nickname, 'account_expired' => false, 'account_removed' => false]);
 		if (!$this->database->isResult($importer)) {
diff --git a/src/Module/Tos.php b/src/Module/Tos.php
index 822aa8813b..11cecac44d 100644
--- a/src/Module/Tos.php
+++ b/src/Module/Tos.php
@@ -77,7 +77,7 @@ class Tos extends BaseModule
 	 */
 	protected function content(array $request = []): string
 	{
-		if (strlen($this->config->get('system', 'singleuser'))) {
+		if ($this->config->get('system', 'singleuser')) {
 			$this->baseUrl->redirect('profile/' . $this->config->get('system', 'singleuser'));
 		}
 
diff --git a/src/Navigation/Notifications/Factory/FormattedNavNotification.php b/src/Navigation/Notifications/Factory/FormattedNavNotification.php
index 2b1360eaa4..9813fbf859 100644
--- a/src/Navigation/Notifications/Factory/FormattedNavNotification.php
+++ b/src/Navigation/Notifications/Factory/FormattedNavNotification.php
@@ -28,7 +28,7 @@ use Friendica\Model\Contact;
 use Friendica\Navigation\Notifications\Entity;
 use Friendica\Navigation\Notifications\Exception\NoMessageException;
 use Friendica\Navigation\Notifications\ValueObject;
-use Friendica\Network\HTTPException\ServiceUnavailableException;
+use Friendica\Network\HTTPException;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy;
 use Friendica\Util\Temporal;
@@ -73,7 +73,7 @@ class FormattedNavNotification extends BaseFactory
 	 * @param Uri       $href
 	 * @param bool      $seen
 	 * @return ValueObject\FormattedNavNotification
-	 * @throws ServiceUnavailableException
+	 * @throws HTTPException\ServiceUnavailableException
 	 */
 	public function createFromParams(string $contact_name, string $contact_url, string $message, \DateTime $date, Uri $href, bool $seen = false): ValueObject\FormattedNavNotification
 	{
@@ -115,9 +115,9 @@ class FormattedNavNotification extends BaseFactory
 	 * @param Entity\Notification $notification
 	 * @return ValueObject\FormattedNavNotification
 	 * @throws NoMessageException
-	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-	 * @throws \Friendica\Network\HTTPException\NotFoundException
-	 * @throws \Friendica\Network\HTTPException\ServiceUnavailableException
+	 * @throws HTTPException\InternalServerErrorException
+	 * @throws HTTPException\NotFoundException
+	 * @throws HTTPException\ServiceUnavailableException
 	 */
 	public function createFromNotification(Entity\Notification $notification): ValueObject\FormattedNavNotification
 	{
@@ -141,10 +141,20 @@ class FormattedNavNotification extends BaseFactory
 		);
 	}
 
+	/**
+	 * @param \Friendica\Contact\Introduction\Entity\Introduction $intro
+	 * @return ValueObject\FormattedNavNotification
+	 * @throws HTTPException\NotFoundException when the contact record couldn't be located
+	 * @throws HTTPException\ServiceUnavailableException
+	 */
 	public function createFromIntro(\Friendica\Contact\Introduction\Entity\Introduction $intro): ValueObject\FormattedNavNotification
 	{
-		if (!isset(self::$contacts[$intro->cid])) {
-			self::$contacts[$intro->cid] = Contact::getById($intro->cid, ['name', 'url', 'pending']);
+		if (empty(self::$contacts[$intro->cid])) {
+			if ($contact = Contact::getById($intro->cid, ['name', 'url', 'pending'])) {
+				self::$contacts[$intro->cid] = $contact;
+			} else {
+				throw new HTTPException\NotFoundException('Contact not found with id' . $intro->cid);
+			}
 		}
 
 		if (self::$contacts[$intro->cid]['pending']) {
diff --git a/src/Network/Probe.php b/src/Network/Probe.php
index d79cd4055f..5a8f75e2d8 100644
--- a/src/Network/Probe.php
+++ b/src/Network/Probe.php
@@ -38,6 +38,7 @@ use Friendica\Network\HTTPClient\Client\HttpClientAccept;
 use Friendica\Network\HTTPClient\Client\HttpClientOptions;
 use Friendica\Protocol\ActivityNamespace;
 use Friendica\Protocol\ActivityPub;
+use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\Email;
 use Friendica\Protocol\Feed;
 use Friendica\Protocol\Salmon;
@@ -134,6 +135,17 @@ class Probe
 			}
 		}
 
+		$newdata['networks'] = [];
+		foreach ([Protocol::DIASPORA, Protocol::OSTATUS] as $network) {
+			if (!empty($data['networks'][$network])) {
+				$data['networks'][$network]['subscribe'] = $newdata['subscribe'] ?? '';
+				$data['networks'][$network]['baseurl'] = $newdata['baseurl'] ?? '';
+				$data['networks'][$network]['gsid'] = $newdata['gsid'] ?? 0;
+				$newdata['networks'][$network] = self::rearrangeData($data['networks'][$network]);
+				unset($newdata['networks'][$network]['networks']);
+			}
+		}
+
 		// We don't use the "priority" field anymore and replace it with a dummy.
 		$newdata['priority'] = 0;
 
@@ -345,7 +357,13 @@ class Probe
 				$data = [];
 			}
 			if (empty($data) || (!empty($ap_profile) && empty($network) && (($data['network'] ?? '') != Protocol::DFRN))) {
+				$networks = $data['networks'] ?? [];
+				unset($data['networks']);
+				if (!empty($data['network'])) {
+					$networks[$data['network']] = $data;
+				}
 				$data = $ap_profile;
+				$data['networks'] = $networks;
 			} elseif (!empty($ap_profile)) {
 				$ap_profile['batch'] = '';
 				$data = array_merge($ap_profile, $data);
@@ -669,7 +687,7 @@ class Probe
 		}
 
 		$parts = parse_url($uri);
-		if (empty($parts['scheme']) && empty($parts['host']) && !strstr($parts['path'], '@')) {
+		if (empty($parts['scheme']) && empty($parts['host']) && (empty($parts['path']) || strpos($parts['path'], '@') === false)) {
 			Logger::info('URI was not detectable', ['uri' => $uri]);
 			return [];
 		}
@@ -716,9 +734,13 @@ class Probe
 		}
 		if ((!$result && ($network == '')) || ($network == Protocol::DIASPORA)) {
 			$result = self::diaspora($webfinger);
+		} else {
+			$result['networks'][Protocol::DIASPORA] = self::diaspora($webfinger);
 		}
 		if ((!$result && ($network == '')) || ($network == Protocol::OSTATUS)) {
 			$result = self::ostatus($webfinger);
+		} else {
+			$result['networks'][Protocol::OSTATUS] = self::ostatus($webfinger);
 		}
 		if (in_array($network, ['', Protocol::ZOT])) {
 			$result = self::zot($webfinger, $result, $baseurl);
@@ -2188,6 +2210,8 @@ class Probe
 			$owner     = User::getOwnerDataById($uid);
 			$approfile = ActivityPub\Transmitter::getProfile($uid);
 
+			$split_name = Diaspora::splitName($owner['name']);
+	
 			if (empty($owner['gsid'])) {
 				$owner['gsid'] = GServer::getID($approfile['generator']['url']);
 			}
@@ -2207,7 +2231,28 @@ class Probe
 				'inbox'            => $approfile['inbox'], 'outbox' => $approfile['outbox'],
 				'sharedinbox'      => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN,
 				'pubkey'           => $owner['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $owner['gsid'],
-				'manually-approve' => in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])
+				'manually-approve' => in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]),
+				'networks' => [
+					Protocol::DIASPORA => [
+						'name'         => $owner['name'],
+						'given_name'   => $split_name['first'],
+						'family_name'  => $split_name['last'],
+						'nick'         => $owner['nick'],
+						'guid'         => $approfile['diaspora:guid'],
+						'url'          => $owner['url'],
+						'addr'         => $owner['addr'],
+						'alias'        => $owner['alias'],
+						'photo'        => $owner['photo'],
+						'photo_medium' => $owner['thumb'],
+						'photo_small'  => $owner['micro'],
+						'batch'        => $approfile['generator']['url'] . '/receive/public',
+						'notify'       => $owner['notify'],
+						'poll'         => $owner['poll'],
+						'poco'         => $owner['poco'],						
+						'network'      => Protocol::DIASPORA,
+						'pubkey'       => $owner['upubkey'],
+					]
+				]
 			];
 		} catch (Exception $e) {
 			// Default values for non existing targets
diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php
index 8e21a66446..d098ddb691 100644
--- a/src/Protocol/ActivityPub/Processor.php
+++ b/src/Protocol/ActivityPub/Processor.php
@@ -804,7 +804,7 @@ class Processor
 	private static function processContent(array $activity, array $item)
 	{
 		if (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/markdown')) {
-			$item['title'] = strip_tags($activity['name']);
+			$item['title'] = strip_tags($activity['name'] ?? '');
 			$content = Markdown::toBBCode($activity['content']);
 		} elseif (!empty($activity['mediatype']) && ($activity['mediatype'] == 'text/bbcode')) {
 			$item['title'] = $activity['name'];
@@ -1273,8 +1273,11 @@ class Processor
 				foreach ($receivers[$element] as $receiver) {
 					if ($receiver == ActivityPub::PUBLIC_COLLECTION) {
 						$name = Receiver::PUBLIC_COLLECTION;
+					} elseif ($path = parse_url($receiver, PHP_URL_PATH)) {
+						$name = trim($path, '/');
 					} else {
-						$name = trim(parse_url($receiver, PHP_URL_PATH), '/');
+						Logger::warning('Unable to coerce name from receiver', ['receiver' => $receiver]);
+						$name = '';
 					}
 
 					$target = Tag::getTargetType($receiver);
diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php
index 4e2bcceafb..8939822742 100644
--- a/src/Protocol/ActivityPub/Receiver.php
+++ b/src/Protocol/ActivityPub/Receiver.php
@@ -209,7 +209,7 @@ class Receiver
 				Logger::notice('No object data found', ['type' => $type, 'object_type' => $object_type, 'object_id' => $object_id, 'actor' => $actor, 'activity' => $activity]);
 				return;
 			}
-	
+
 			if (self::routeActivities($object_data, $type, true)) {
 				Logger::debug('Handled activity', ['type' => $type, 'object_type' => $object_type, 'object_id' => $object_id, 'actor' => $actor]);
 			} else {
@@ -1472,7 +1472,7 @@ class Receiver
 				continue;
 			}
 
-			$element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type')),
+			$element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type') ?? ''),
 				'href' => JsonLD::fetchElement($tag, 'as:href', '@id'),
 				'name' => JsonLD::fetchElement($tag, 'as:name', '@value')];
 
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index 3c60f4041b..fe5b27d334 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -826,9 +826,15 @@ class Diaspora
 	 */
 	public static function isSupportedByContactUrl(string $url, ?bool $update = null): bool
 	{
-		$contact = Contact::getByURL($url, $update);
+		$contact = Contact::getByURL($url, $update, ['uri-id', 'network']);
 
-		return DI::dsprContact()->existsByUriId($contact['uri-id'] ?? 0);
+		$supported = DI::dsprContact()->existsByUriId($contact['uri-id'] ?? 0);
+
+		if (!$supported && is_null($update) && ($contact['network'] == Protocol::DFRN)) {
+			$supported = self::isSupportedByContactUrl($url, true);
+		}
+
+		return $supported;
 	}
 
 	/**
@@ -4064,7 +4070,7 @@ class Diaspora
 			return false;
 		}
 
-		if (!self::isSupportedByContactUrl($parent_post['author-link'], false)) {
+		if (!self::isSupportedByContactUrl($parent_post['author-link'])) {
 			Logger::info('Parent author is no Diaspora contact.', ['parent-id' => $parent_id]);
 			return false;
 		}
diff --git a/src/Protocol/Diaspora/Entity/DiasporaContact.php b/src/Protocol/Diaspora/Entity/DiasporaContact.php
index 7fbd2831f7..a5ad1f08af 100644
--- a/src/Protocol/Diaspora/Entity/DiasporaContact.php
+++ b/src/Protocol/Diaspora/Entity/DiasporaContact.php
@@ -82,7 +82,7 @@ class DiasporaContact extends \Friendica\BaseEntity
 	protected $notify;
 	/** @var UriInterface */
 	protected $poll;
-	/** @var UriInterface */
+	/** @var string URL pattern string including a placeholder "{uri}" that mustn't be URL-encoded */
 	protected $subscribe;
 	/** @var bool */
 	protected $searchable;
@@ -107,7 +107,7 @@ class DiasporaContact extends \Friendica\BaseEntity
 		UriInterface $url, \DateTime $created, string $guid = null, string $addr = null, UriInterface $alias = null,
 		string $nick = null, string $name = null, string $givenName = null, string $familyName = null,
 		UriInterface $photo = null, UriInterface $photoMedium = null, UriInterface $photoSmall = null,
-		UriInterface $batch = null, UriInterface $notify = null, UriInterface $poll = null, UriInterface $subscribe = null,
+		UriInterface $batch = null, UriInterface $notify = null, UriInterface $poll = null, string $subscribe = null,
 		bool $searchable = null, string $pubKey = null, UriInterface $baseurl = null, int $gsid = null,
 		\DateTime $updated = null, int $interacting_count = 0, int $interacted_count = 0, int $post_count = 0, int $uriId = null
 	) {
diff --git a/src/Protocol/Diaspora/Factory/DiasporaContact.php b/src/Protocol/Diaspora/Factory/DiasporaContact.php
index d5c91d200b..0389b81ee6 100644
--- a/src/Protocol/Diaspora/Factory/DiasporaContact.php
+++ b/src/Protocol/Diaspora/Factory/DiasporaContact.php
@@ -45,7 +45,7 @@ class DiasporaContact extends \Friendica\BaseFactory implements ICanCreateFromTa
 			$row['batch'] ? new Uri($row['batch']) : null,
 			$row['notify'] ? new Uri($row['notify']) : null,
 			$row['poll'] ? new Uri($row['poll']) : null,
-			$row['subscribe'] ? new Uri($row['subscribe']) : null,
+			$row['subscribe'],
 			$row['searchable'],
 			$row['pubkey'],
 			$row['baseurl'] ? new Uri($row['baseurl']) : null,
@@ -87,7 +87,7 @@ class DiasporaContact extends \Friendica\BaseFactory implements ICanCreateFromTa
 			$data['batch'] ? new Uri($data['batch']) : null,
 			$data['notify'] ? new Uri($data['notify']) : null,
 			$data['poll'] ? new Uri($data['poll']) : null,
-			$data['subscribe'] ? new Uri($data['subscribe']) : null,
+			$data['subscribe'],
 			!$data['hide'],
 			$data['pubkey'],
 			$data['baseurl'] ? new Uri($data['baseurl']) : null,
diff --git a/src/Protocol/Diaspora/Repository/DiasporaContact.php b/src/Protocol/Diaspora/Repository/DiasporaContact.php
index ac8d200aa8..1669707b92 100644
--- a/src/Protocol/Diaspora/Repository/DiasporaContact.php
+++ b/src/Protocol/Diaspora/Repository/DiasporaContact.php
@@ -234,6 +234,18 @@ class DiasporaContact extends BaseRepository
 	 */
 	public function updateFromProbeArray(array $data): Entity\DiasporaContact
 	{
+		if (empty($data['url'])) {
+			throw new \InvalidArgumentException('Missing url key in Diaspora probe data array');
+		}
+
+		if (empty($data['guid'])) {
+			throw new \InvalidArgumentException('Missing guid key in Diaspora probe data array');
+		}
+
+		if (empty($data['pubkey'])) {
+			throw new \InvalidArgumentException('Missing pubkey key in Diaspora probe data array');
+		}
+
 		$uriId = ItemURI::insert(['uri' => $data['url'], 'guid' => $data['guid']]);
 
 		$contact   = Contact::getByUriId($uriId, ['id', 'created']);
diff --git a/src/Protocol/Feed.php b/src/Protocol/Feed.php
index 29b1923316..dec463820d 100644
--- a/src/Protocol/Feed.php
+++ b/src/Protocol/Feed.php
@@ -625,8 +625,8 @@ class Feed
 
 			$notify = Item::isRemoteSelf($contact, $item);
 
-			// Distributed items should have a well formatted URI.
-			// Additionally we have to avoid conflicts with identical URI between imported feeds and these items.
+			// Distributed items should have a well-formatted URI.
+			// Additionally, we have to avoid conflicts with identical URI between imported feeds and these items.
 			if ($notify) {
 				$item['guid'] = Item::guidFromUri($orig_plink, DI::baseUrl()->getHostname());
 				$item['uri'] = Item::newURI($item['guid']);
diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php
index cec894480c..1a0758987a 100644
--- a/src/Worker/Delivery.php
+++ b/src/Worker/Delivery.php
@@ -277,7 +277,7 @@ class Delivery
 	private static function deliverDFRN(string $cmd, array $contact, array $owner, array $items, array $target_item, bool $public_message, bool $top_level, bool $followup, int $server_protocol = null)
 	{
 		// Transmit Diaspora reshares via Diaspora if the Friendica contact support Diaspora
-		if (Diaspora::getReshareDetails($target_item ?? []) && Diaspora::isSupportedByContactUrl($contact['addr'], false)) {
+		if (Diaspora::getReshareDetails($target_item ?? []) && Diaspora::isSupportedByContactUrl($contact['addr'])) {
 			Logger::info('Reshare will be transmitted via Diaspora', ['url' => $contact['url'], 'guid' => ($target_item['guid'] ?? '') ?: $target_item['id']]);
 			self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup);
 			return;
diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php
index db593b6a47..c09faca89b 100644
--- a/src/Worker/Notifier.php
+++ b/src/Worker/Notifier.php
@@ -191,7 +191,7 @@ class Notifier
 			// when the original comment author does support the Diaspora protocol.
 			if ($thr_parent['author-link'] && $target_item['parent-uri'] != $target_item['thr-parent']) {
 				$diaspora_delivery = Diaspora::isSupportedByContactUrl($thr_parent['author-link']);
-				if ($diaspora_delivery &&  empty($target_item['signed_text'])) {
+				if ($diaspora_delivery && empty($target_item['signed_text'])) {
 					Logger::debug('Post has got no Diaspora signature, so there will be no Diaspora delivery', ['guid' => $target_item['guid'], 'uri-id' => $target_item['uri-id']]);
 					$diaspora_delivery = false;
 				}
diff --git a/view/theme/frio/js/module/admin/logs/view.js b/view/theme/frio/js/module/admin/logs/view.js
index 9faf9ec890..ab07882d27 100644
--- a/view/theme/frio/js/module/admin/logs/view.js
+++ b/view/theme/frio/js/module/admin/logs/view.js
@@ -6,7 +6,7 @@ $(function(){
 		var value = this.dataset.filterValue;
 		var re = RegExp(filter+"=[a-z]*");
 		var newhref = location.href;
-		if (!location.href.indexOf("?") < 0) {
+		if (location.href.indexOf("?") < 0) {
 			newhref = location.href + "?" + filter + "=" + value;
 		} else if (location.href.match(re)) {
 			newhref = location.href.replace(RegExp(filter+"=[a-z]*"), filter+"="+value);